Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push support - including complicated ones #50

Closed
dfishburn opened this issue Dec 3, 2015 · 8 comments
Closed

Push support - including complicated ones #50

dfishburn opened this issue Dec 3, 2015 · 8 comments

Comments

@dfishburn
Copy link

I see on the homepage you have:
Add a push function, taking care if needed about the remote repository and branch.

It would be nice to have some way to configure this via the vimrc.

For example the Perforce (source control) plugin allows you to specify which servers to use:
let g:p4Presets = ['port1 client1 user1', 'port2 client2 user2' ]

Then you can use :PFSwitch 1 to choose the first item in the List. This allows me to configure a buffer based on autocmds.

My git push commands with Gerrit look like this:

git push ssh://me@git:29418/my.server.git HEAD:refs/for/master

This is too difficult to remember (much longer than supplied above) and I have many to choose from.
So, I would like to be able to use an autocmd based on my directory to choose the correct "push" command for the project I am in. Then use a P or whatever mapping to run it.

Thanks,
David

@jreybert
Copy link
Owner

jreybert commented Dec 4, 2015

Hi David,

thanks for your report, it is reaaly helpful to get workflows from other people!

I am not sure to fully understand the perforce worklow, do you have a link to a usage example?

Thanks

@dfishburn
Copy link
Author

Don't worry about the P4 workflow as it is different.

Basically, I stage a bunch of changes.
Then I CC and commit the change.
Now I want to git push those changes.

The git push command I have to run is complicated, so I want those stored somewhere.

Then in the :Magit window, just like hitting CC, I want to hit PP (or something) to do a git push, but the actual command run by :Magit would be a custom command I provided (assuming I provided one, otherwise, it will run the standard git push.

In my .vimrc I have augroups for different projects, which allow me to "customize" my Vim settings and plugins for that project. Consider this one:

augroup Project1
    au!
    " Automatically choose the correct dbext profile
    autocmd BufRead */Project1/* if exists('g:loaded_dbext') | exec 'DBSetOption profile=ASA_Project1' | endif
    autocmd BufRead */Project1/**/web/*
                \ setlocal sw=4 noexpandtab tabstop=4|
    autocmd BufWritePost */Project1/**/web/*
                \ if &filetype == 'javascript' && exists('b:current_compiler') && b:current_compiler == 'eslint' && !exists('b:do_not_compile') | make | cwindow | endif 
augroup end

I create an augroup for each project I work on.

What I would do with Vimagit, is based on the directory I am in, I would override the git push command with one of my stored values.

Vimagit, would need to provide the ability for me to override that command though. We can't really do this at a buffer level using b: variables, since we could be many directories deep in the project.

I am not sure what Vimagit provides, but I would think something like this:

let g:magit_settings= {
    'Project1' : {
                        'magit_git_cmd' : '"C:\Program Files\Git\cmd\git.EXE"',
                        'magit_push' : 'ssh://[email protected]:29418/project1.git HEAD:refs/for/master'
                     },
    'Project2' : {
                        'magit_push' : 'current'
                     }
}

"Project1", would have to be something returned from git.

You already do this:

$ git  rev-parse --show-toplevel
C:/source/Project1

So maybe the dictionary of settings we store in the .vimrc can be keyed off some "thing" we get from git. I am extremely new to git, so I am not sure what that would be. But it just needs to be something to allow us to configure based on the directory we are in.

Anyway, those are just ideas.

I have given you two basic options:

  1. Allow me in my own autocmds, to configure :Magit in some way for the current repository
  2. Allow me in my .vimrc, to specify some overrides using Vim dictionaries keyed off of something git returns identifying which repository we are in, and specify certain settings / commands.

@jreybert
Copy link
Owner

jreybert commented Dec 5, 2015

Basically, for the moment, I am thinking to provide this function:
function! magit#push(remote_name, remote_branch_name)

remote_name and remote_branch_name are optional.

When these parameters are set, the current branch is pushed silently.

When the parameters are not set (ie. the user calls magit#push(), an input is prompt to ask the user to set the remote name, then to set the remote branch name. These input will be prefilled with git default. git default depends on user settings.

While I'm at it, I advise you to have a look on git remote settings.

  • instead of pushing on a raw ssh url, why don't you set a remote? eg.
git remote add project1 ssh://[email protected]:29418/project1.git

this remote setting will be local to your repository.

  • It is possible to set a default push remote for:
    • the current repository: git config remote.pushDefault project1
    • a specific branch: git config branch.<name>.pushRemote project1
  • It is also possible to set a default remote branch for a given branch:
    git config branch.<name>.merge team/master

Finally, set upstream push default behabior: git config push.default upstream

All that to say that it seems safer to let git handle this kind of stuff. Anyway, if you really prefer to handle your remote url and remote branch from vim, you always can wrap magit#push in your own function, and map this function.

If you think that this solution is not yet enough for you, feel free to say it ;)

@jreybert
Copy link
Owner

jreybert commented Dec 5, 2015

BTW, let the user the opportunity to define it's own git command is a good idea!

Do you really need different git commands among projects?

@jreybert
Copy link
Owner

jreybert commented Feb 8, 2016

This issue is related to #24

@jreybert jreybert modified the milestone: Release 1.6.0 Feb 9, 2016
@dfishburn
Copy link
Author

I downloaded the master branch today.
Unfortunately, I am not certain how to test this enhancement.

When I open the :Magit window, then do:
:call magit

I don't see anything resembling "push".
When I open doc\magit.txt, there is nothing in there related to push.

Ahh, I see the problem, I had to use the "dev-push" branch not "master".

First problem with this branch, is it does not have my changes to make it work under Windows.
So I had to debug and make the same changes to autoload\magit\git.vim to use my custom git command.
Now I am getting another error, now that I have found the magit#push() command.

Error detected while processing function magit#push[3]..magit#git#default_remote[3]..magit#utils#system:
line    7:
E484: Can't open file C:\Temp\VIo3844.tmp

Looking at the code in the Vim debugger:

function magit#push[3]..magit#git#default_remote[3]..magit#utils#system
line 7: return call('system', a:000)
>echo call('system', a:000)
E484: Can't open file C:\Temp\VIo3DCC.tmp
>echo a:000
['"C:\Program Files\Git\cmd\git.EXE" for-each-ref --format=''%(push:short)'' refs/heads/master'] 

Should this line:

return call('system', a:000)

Be:

call system(a:000)

Hmm, I tried these variants, all failed:

function! magit#utils#system(...)
    let dir = getcwd()
    try
        execute s:magit_cd_cmd . magit#git#top_dir()
        " List as system() input is since v7.4.247, it is safe to check
        " systemlist, which is sine v7.4.248
        if exists('*systemlist')
                        return call('systemlist', a:000)
            return system(a:000)
            " DF
                        " return call('system', a:000)

Not sure what you were trying to accomplish.

@jreybert
Copy link
Owner

Hey, good to see how active you are!

This is a quite old dev branch, I have to refresh my memory, I am not event sure this branch is working!

I rebased the dev/push branch onto next, and repushed it (you should have do the rebase instead of apply again your patches). Could you try with the forced updated dev/push branch?

About
return call('system', a:000)
vimagit is using systemlist a lot (because it faster), but this function appeared quite recently in vim. So, I wrapped system in magit#utils#system. As system takes a varaible number of arguments, I must go through call('system', a:000)

And the return value os system is important :)

@jreybert jreybert modified the milestone: Release 1.6.0 Mar 3, 2016
@jreybert
Copy link
Owner

jreybert commented Aug 8, 2017

This issue is closed, comment on issue #24 or on gitter

@jreybert jreybert closed this as completed Aug 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants