[Insight-developers] some useful git commands for ITK

Brad King brad.king at kitware.com
Mon Aug 2 12:18:22 EDT 2010


On 08/02/2010 11:05 AM, Gaëtan Lehmann wrote:
> # one time configuration on each host
> 
> git config --global user.name "Gaëtan Lehmann"
> git config --global user.email "gaetan.lehmann at jouy.inra.fr"
> git config --global color.ui auto

Good.

> git config --global core.pager "less -FXRS"

I've never set this, but your explanation on the Wiki looks good.

> # to use the same ssh key to commit to itk.org from different hosts
> # the key can be generated with ssh-keygen -t rsa -N "" -f ~/.ssh/ 
> id_git_itk
> scp marvin:.ssh/id_git_itk ~/.ssh/id_git_itk
> echo "Host itk.org" >> ~/.ssh/config
> echo "  IdentityFile=~/.ssh/id_git_itk" >> ~/.ssh/config

Good.

This is not just a convenience, but a requirement.  We allow at most
one public key per developer.  You must share the private key among
all machines from which you want to push.  (Of course you can always
push privately to your own single computer with that private key and
then use that one to push to "git at itk.org:ITK.git".)

Use a passphrase; ssh-agent is not that hard ;)

> # get ITK and its submodules
> git clone git://itk.org/ITK.git
> cd ITK
> git submodule update --init

Even simpler with Git 1.6.5 or higher:

  git clone --recursive git://itk.org/ITK.git

I updated the Wiki's clone instructions:

  http://www.itk.org/Wiki/ITK/Git#Cloning

> # configure the push url
> git config remote.origin.pushurl git at itk.org:ITK.git

Good.

> # get the hooks to run locally
> cd .git/hooks
> git init
> git pull .. remotes/origin/hooks
> cd ../..

Good.

> # to update the repository
> git pull --rebase

This works if your current local branch is "master" but will not if
you're on a local topic branch.  If you avoid doing commits directly
in master and always work on a topic, then you should never need to
"update" the repository during development.  Instead use

 git checkout master
 git pull
 git checkout -b my-new-topic

to start new work.  To continue old work just do

 git checkout my-old-topic

See here for an explanation of why constant merging from upstream
with Git should not be done:

  http://public.kitware.com/Wiki/Git/Workflow/Topic#Urge_to_Merge

> # to update the hooks
> git fetch origin
> cd .git/hooks
> git pull .. remotes/origin/hooks

Good.

> # view changes
> git diff  # only non-indexed changes (without git add)
> git diff --cached # only indexed changes (with git add) - what you're  
> about to commit with git commit (without -a)

Good.

> git diff HEAD # both indexed and non-indexed changes

In practice it looks like the aggregate of the indexed and non-indexed
changes, but strictly speaking this is a diff between the HEAD commit
and your work tree.  The contents of the index are irrelevant.

> # to revert all the changes - recorded patch are not lost
> git reset --hard  # revert all the changes - indexed and non indexed

Good.  Be careful with this one ;)

FYI, once you've done "git add" to stage something then it is in the
local repository.  Even after a hard reset you can recover it if you
know how.

> # to revert the changes in specific file(s)
> git checkout -- a_file # do NOT revert the indexed changes (with git  
> add)

Yes, this copies the file from the index to the work tree.
You can also do

 git checkout HEAD -- a_file

to copy the file from the HEAD commit to the index and work tree
(or from any commit in place of HEAD).

> # to commit some changes and push it in the main repository
> git add a_file  # -p can be handy to select only a part of the changes
> git commit -s  # -a can be handy to commit everything without the need  
> to run git add
> git push  # actually publish the committed patch on itk.org

This is good for simulating our old CVS-based workflow and work
directly on master.

> # to rewrite the message of the last commit
> git commit --amend

Correct.  However, do *not* do this for any commits you've already
pushed!  You will end up with empty, duplicated, or conflicting
commits the next time you try to publish.

> # uncommit the last patch
> git reset HEAD^  # changes are not lost, just uncommited

Good.  This moves the local branch pointer back to the previous
commit and updates the index but leaves the work tree alone.
The end result is the appearance of un-commit.

> git reset --hard REVISION~1 # changes are lost (!!!)

If they were committed prior to this then you can get them back.
Take a look at "git help reflog" and "git help rev-parse" for
reflog reference syntax.  Immediately after this command you
can do

  git reset --hard HEAD@{1}

to get your commit back.

> git revert  # generates a new patch to revert the previous one - to be  
> used only if the previous patch has been published

Good.

> # view patch history
> git log --stat # on the full repository, with the list of modified files

Good.  I use this frequently.

> git log a_file # on a single file

Good.  You can also do

  git log --follow -- a_file

to follow its log through renames.

> git show patch_id # the content of a patch

Good.  Replace "patch_id" with "commit-ish" to use Git terminology.
("Patch-id" actually means something different internally to Git.)

> # view unpushed (unpublished) patches
> git log origin..

This is better written

  git log origin/master..

Using just "origin" depends on refs/remotes/origin/HEAD to tell
you the upstream default branch.

Also, strictly speaking this command views commits reachable in
the history DAG from your HEAD (current branch) but not reachable
from origin/master.  Some of the commits may be published if there
are multiple upstream branches or if you have not fetched from
origin in a while.

-Brad


More information about the Insight-developers mailing list