Table of Contents
GIT - The Stupid Content Tracker
Here are some thoughts about git
. No basic stuff, mostly best practices I
discovered by (and for) myself.
Juggling Around Remotes
Assume a local project named proj and a new remote clone at [git:bla.org/proj.git]. First add the new remote: ~/git/proj % git remote add bla git:bla.org/proj.git
see what you've got:
~/git/proj % git remote show bla
next, do an initial fetch of the remote's content:
~/git/proj % git fetch bla
see the remote's branches:
~/git/proj % git br -r | grep bla/
assuming bla is upstream and you have local commits to apply on top of it, first rebase your local master onto bla/master, changing the history of your local branch:
~/git/proj % git rebase bla/master master
then you can fast-forward push the new local patches:
~/git/proj % git push bla master:master;
assuming you are upstream and bla has published commits to apply on top of yours, you can first check if the remote's master is up to date:
~/git/proj % git log bla/master..master
the commits you see in the log (if any) are the changes contained in your local master, but not in bla/master. If there are none, there is no need for merging, pulling from the remote branch will result in a fast-forward. Next, check what the remote has for us:
~/git/proj % git log master..bla/master
depending on the amount of commits and personal taste of course, there are several options to apply the remote commits to one's local branch. E.g. one can pick them one by one:
~/git/proj % git cherry-pick <commit-id>
or simply merge the branch into yours:
~/git/proj % git merge bla/master
Editing History
The following stuff is not meant for published clones as those should keep their history consistent. But it's very useful for local development, especially housekeeping tasks such as fixing up buggy commits in the past.
Dropping A Past Commit
The command seems easy:
~/git/proj % git rebase --onto <commit-id-A> <commit-id-B>
the trick is getting the commit-ids right:
* commit-id-A is the last commit before the one to be dropped * commit-id-B is the actual commit to be dropped
so in a history like this:
A--B--C--D
issuing the following command:
~/git/proj % git rebase --onto B C
will lead to this:
A--B--D
you can even skip a row of commits:
~/git/proj % git rebase --onto B D
and you get:
A--D
Editing Past Commits
I use a temporary branch for these things:
~/git/proj % git branch hist <commit-to-change>
do your stuff and amend the commit:
~/git/proj % git checkout hist ~/git/proj % vim bla blub ~/git/proj % git commit -a --amend
finally rebase the original branch on top of hist and drop the temporary branch:
~/git/proj % git rebase hist master ~/git/proj % git branch -d hist
note that conflicts here are quite common, especially for the first commit
from master being applied by git rebase
, as in fact that's the commit
which has been corrected and should be dropped.
Cloning via SSH
Using SSH as transport is trivial, as it's widely used for repositories with
write access. The URL to use for git clone
or git remote
looks like
this:
ssh://[user@]example.com[:port]/path/to/repo.git/
An alternative, “scp-like” syntax is supported as well:
[user@]example.com:path/to/repo.git/
Specifying the SSH Identity
Sometimes it's not sufficient to clone via SSH and relying upon the first
accepted key in ssh-agent
. A practical example is having multiple accounts
in Github - like with gitolite
, all users connect using a common username
and are distinguished based on pubkey. This may be given during clone like so, according to a popular answer on StackOverflow:
git clone -c core.sshCommand="/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo" git@github.com:me/repo.git
Or fixed after the fact in the local repo's config:
git config --local core.sshCommand "/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo"