Skip to main content

Using git

Here are some common git operations for which we often find ourselves searching.

Workflow

Checkout a remote branch 'develop' and keep it linked to the origin:

git checkout -t origin/develop

It should report: "Branch develop set up to track remote branch develop from origin."

List all branches (both local and remote):

git branch -a

List local branches and their corresponding upstream remote branches:

git branch -vv

Revert local changes to 'filename' (prior to commit):

git checkout filename

Revert all local changes to the current subtree (prior to commit):

git checkout .

Cute hack to revert all local changes (prior to commit):

git stash
git stash drop

Undo a commit:

git reset --soft HEAD^

Update to latest HEAD, preserving local changes and local commits on top:

git stash
git pull --rebase
git stash pop

Push changes on master to origin:

git push origin master

Delete untracked files and directories:

git clean -df

Interactively stage patches from changed file(s):

git add -p <path>

Branches

Branch master to a new local branch "new_branch":

git checkout -b new_branch master

Push local branch to remote:

git push -u origin new_branch

Make an existing local branch start tracking a corresponding remote branch (not necessary if you used "git push -u" as suggested above):

git branch --set-upstream new_branch origin/new_branch

List the local branches that have already been merged to this one:

git branch --merged

Delete a branch both locally and remotely:

git branch -rd origin/branch_to_kill
git branch -d branch_to_kill
git push origin :branch_to_kill

Move a commit from bad_branch to good_branch:

# First remove the commit from the bad branch:
git checkout bad_branch
git rebase -i
# Change the undesirable commit to "noop"

# Then checkout the correct branch:
git checkout good_branch
# And cherry pick the commit out of the reflog:
git cherry-pick bad_branch@{1}

For more on branching, see the notes on the Fiji wiki.

Git + SVN

Clone an SVN repository to a local Git repository:

git svn clone -s http://code.imagej.net/svn/imagej

Commit and push changes, even with local changes in the working copy:

git commit
git stash
git svn dcommit
git stash pop

Update to latest trunk, preserving local changes and local commits on top:

git stash
git svn rebase
git stash pop

Scripts

There are some scripts available as part of the scijava-common project.

List information about all remote branches including last author, commit date and unmerged commit count:

$SCIJAVA/bin/remote-branch-info.sh

Advanced and/or dangerous

Push all remote branches from one origin (e.g., "origin") to another (e.g., "github"):

git push github $(git for-each-ref refs/remotes/origin | grep -v HEAD | while read sha1 type ref; do echo $ref:refs/heads/${ref#refs/remotes/origin/}; done)

Split a subdirectory into a separate git repository:

See these posts on Stack Overflow:

Rewrite history to throw away git-svn-id metadata:

git filter-branch --msg-filter '
sed -e "/^git-svn-id:/d"
'

Fully garbage collect and compact the repository (deletes all orphaned refs!):

git reset --hard
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
git gc --aggressive --prune=now