Reputation: 1663
I am using the "Integration-Manager" workflow with Git, while using gitolite for permission management. Gitolite has this neat option for easily managing personal user branches in:
refs/personal/USERNAME/USERBRANCHNAME
In our case, these are the only branches to which the developers have write access. This means they are routinely pulling from the "blessed" repository, which is the "master" branch on the "origin" remote, like so:
$ git pull origin master
However, they need to routinely push their work back up to their personal branches, like so:
$ git push origin master:refs/personal/mysuername/mybranchname
Typing those long branch names gets old, really fast, especially for the integrator, who is having to pull routinely from various, long branch names. Most people want to type something simpler, like:
$ git push origin master:mybranchname
So, my question is, "How do I make this easier with shorter names and reduced typos?" Is there some way to create an alias or shortcut for the user's remote branch? Our integrator would like to be able to create aliases for each of the developers to simplify her commands also.
Also, is it possible to configure git to always pull from one branch and push to a different branch without having to specify the remote and branch names in both cases? This would help our developers, although it would not help our integrator. ... I'm familiar with configuring a single default to push and pull from the same remote and branch, but that does not work in this case, since the push and pull branches are different.
Thanks!
Upvotes: 4
Views: 2596
Reputation: 1663
Thanks to all for the input and suggestions. Here's how I got my developers and integrators to use bare git push
and git pull
:
In the simplest integration-manager workflow, as described above, the developer has cloned (git clone
) and is therefore automatically tracking the remote master branch in her local master branch, so all she needs is:
git pull
To update her local master branch. If she is working in some other branch, then she can update the upstream branch that is is tracking, as Adam suggested:
git branch --set-upstream MYOLDBRANCH origin/master
# or, use longer, more explicit syntax, like:
git branch --set-upstream MYOLDBRANCH refs/remotes/origin/master
The tracked branch (origin/master, in this case) will be pulled by default.
Since the default push target is a different branch and not the same name, we cannot take advantage of the push.default being: tracking, current, or matching. Instead, our developer must set the default source:destination refspec for all pushes to a given remote in her .git/config file, like so:
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = GITREPOHOSTNAME:REPONAME
push = master:refs/personal/MYDEVNAME/MYBRANCHNAME
She could also create an alias, like so:
git config alias.pushToMyBr 'push origin master:refs/personal/MYDEVNAME/MYBRANCHNAME
Aliases are very powerful and offer the ultimate flexibility in avoiding keystrokes. :-) The above case can be executed with a simple:
git pushToMyBr
In this simple case, the integrator usually pushes to one place, origin/master. If the push.default is set to matching, tracking, or current, then a bare push will work, like so:
git config push.default current
git checkout master
git push
The frequent pull from various personal developer branches is the more difficult case. The integrator can use aliases to simplify the task, like so:
git config alias.pullFromXY 'pull origin refs/personal/DEVNAMEX/BRANCHNAMEY:master
# or, pull to a specific topic branch
git config alias.pullFromABtoC 'pull origin refs/personal/DEVNAMEA/BRANCHNAMEB:branchC'
The integrator can also create branches to track the developer's personal remote branches, like so:
git checkout -b test_devXbranchY origin/personal/DEVNAMEX/BRANCHNAMEY
# or, use a more specific syntax:
git checkout -b test_devXbranchY refs/remotes/origin/personal/DEVNAMEX/BRANCHNAMEY
For this to work, the integrator must add personal branches to her fetch list. This can be accomplished by directly editing her .git/config, like so: (I don't know how to do this with a git-config or any other git command.)
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = MYGITHOSTNAME:MYREPONAME
fetch = +refs/personal/*:refs/remotes/origin/personal/*
# Fetch a specific developer's branches:
fetch = +refs/personal/devX/*:refs/remotes/origin/personal/devX/*
Thanks to all for the help! Hope this helps someone else who uses gitolite and personal branches outside of head-space.
Thanks!
Trevor
Upvotes: 1
Reputation: 11916
Note: The following ignores gitolite because I don't know how it works.
Instead of tracking the master branch, each developer could track their own personal branch. When they want updates, they can merge them from the master. (It sounds like your current setup is the opposite: Everyone tracks master and is pushing manually.)
Also, don't forget about tab completion. For me on Ubuntu using bash, typing git push origin o<TAB>
will complete to origin/
and then another Tab will show a list of available branches.
If your integrator has the repo checked out into ~/prj
:
integrator:~/prj$ git push origin master:trevor-personal
integrator:~/prj$ git push origin master:pydave-personal
Each developer can clone using their personal branch.
trevor:~$ git clone /path/to/master/repo.git -b trevor-personal prj
pydave:~$ git clone /path/to/master/repo.git -b pydave-personal prj
Or they can checkout a new branch in their existing clone that tracks their personal branch on origin.
pydave:~/prj$ git checkout -b personal origin/pydave-personal
Alternatively, we could use set-upstream if we want to use an existing branch.
pydave:~/prj$ git branch --set-upstream personal origin/pydave-personal
Post a change to developer branch.
trevor:~/prj$ git commit -am'changed something'
trevor:~/prj$ git push
Merge it.
integrator:~/prj$ git pull
integrator:~/prj$ git push origin origin/trevor-personal:master
Retrieve changes from master branch. (We have to be specific about using origin's master. git pull
will just merge changes in pydave-personal
pydave:~/prj$ git pull origin master
Upvotes: 1
Reputation: 129594
Yes. Just track the branch with one of a different name. See the manual page for git branch and things like --set-upstream.
Hope this helps.
Upvotes: 4