Git notes
Here are some notes I find handy for using git.
§ Looking at stuff
- See a log of commits.
git log --graph --decorate --stat # Good compromise
git log --graph --decorate --stat -p # To see detailed diffs
git log --graph --decorate --oneline # For longer histories
|
- See the origin and branches of a working copy:
git config --get remote.origin.url
git remote show origin
git config -l
git branch -a -v
|
- See the unique hash for any file:
git hash-object --no-filters filename
|
- See if a file
Foo.java
is being tracked, maybe just staged for a commit
git ls-files -s | grep Foo.java
|
- See all ways to specify a revision:
https://git-scm.com/docs/gitrevisions
- Find the ten biggest files in your repo
git ls-tree -r -l --full-name HEAD | sort -n -r -k 4 | head -n 10
|
§ Setup
- Make a bare copy, and add as a new remote so that you can push to it.
cd repo # go to repository
git clone --bare `pwd` /backup/repo.git # make bare copy
git remote add backup /backup/repo.git # give it a name
git push backup # for updates
git remote -v # see new remote
|
- Add upstream (if doesn't already exist) and track.
git remote add upstream https://github.com/USERNAME/repo.git
git branch -u upstream/master master
|
- Change an existing origin or upstream, and track master.
git remote set-url origin $HOME/Dropbox/git/repo.git
git branch -u origin/master master
git remote set-url upstream /path/repo.git
git branch -u upstream/master master
|
- Set an upstream for current branch the first time you push
git push -u origin [current_branch]
|
- Improve performance on NFS:
git config core.preloadindex true
|
- Mirror a repo:
git clone --mirror repo_url
git fetch --all # to update
|
- For better diffs by default:
git config --global diff.algorithm patience
|
§ Fixing stuff
- Redo the last commit, before having pushed
git commit -m "Bad commit"
git reset HEAD~ # keeps changes as uncommited, unless --hard
[edits]
git remove [stuff]
git add [stuff]
git commit -c ORIG_HEAD # Reuses previous commit message; otherwise
git commit # Make new commit message
|
- Edit commit message after commiting and before pushing.
- Undo a merge. (Try to avoid using --hard for any resets.)
git reset --merge ORIG_HEAD
|
- Revert a pushed commit.
git revert 123ab...
git commit
|
- To revert just some files in a pushed merge.
git revert --no-commit 123ab...
git reset
git add path/file.txt path/directory/
git commit
git reset --hard
|
- Remove a directory from git without affecting local working copy.
git rm --cached -r some_directory/
|
- To undo all commits and edits that have not yet been pushed to the origin.
This is like deleting your working copy and checking out again.
git reset --hard origin/master
|
- Make a detached HEAD point to master
You have done git checkout rev
to look at a revision at some point,
so HEAD now points somewhere different from master (or your current branch).
You want to point HEAD back to master.
$ git checkout master
$ git log --decorate --oneline
a047b24 (HEAD -> master) later revision
...
|
If you have any changes to save, then first stash them, and apply later.
Otherwise, you will be obliged to destroy them with git checkout -f
.
- Making master point to a detached HEAD.
You have done git checkout rev
to look at a revision at some point,
so HEAD now points somewhere different from master (or your current branch).
You want to move master to where HEAD currently is.
If you have any changes to save, then stash them, and apply later.
Otherwise, you will be obliged to destroy them with git checkout -f
and git reset --hard
.
In this case the HEAD points to a later revision than master:
$ git log --decorate --oneline
a047b24 (HEAD) later revision
6e0bc6b (master) earlier revision
|
First, make the HEAD point to master
$ git checkout master
$ git log --decorate --oneline
6e0bc6b (HEAD -> master) earlier revision
|
Next move both back to the later revision
$ git reset a047b24
$ git log --decorate --oneline
a047b24 (HEAD -> master) later revision
6e0bc6b earlier revision
|
Let's begin again with a detached HEAD at
an earlier revision, so master is not visible:
$ git log --decorate --oneline
6e0bc6b (HEAD) earlier revision
|
First, make the HEAD point to master
$ git checkout master
$ git log --decorate --oneline
a047b24 (HEAD -> master) later revision
6e0bc6b earlier revision
|
Now you can move both back to where HEAD used to be
$ git reset 6e0bc6b
$ git log --decorate --oneline
6e0bc6b (HEAD -> master) earlier revision
|
- Get file contents at a particular revision.
You want to get some files as they looked after a particular commit,
but the commit may not have directly affected those files.
First you find the commit hash you want with
and you find a commit 4e7e2793026f
on November 17, a moment at which you liked a particular file,
even though that commit did not change that file.
You can cat the contents of a file FT.java
at that revision two ways
git show 4e7e2793026f:./FT.java
git cat-file -p 4e7e2793026f:./FT.java
|
Use full paths, or use a dot for a path relative to the current directory.
To find the hash of the blob at that particular moment
$ git ls-tree -r 4e7e2793026f | grep FT.java
100644 blob 23df3f17a4af6cc9a55907cc9273729911193b97 FT.java
|
To cat the contents of that file blob:
git show 23df3f17a4af6
git cat-file -p 23df3f17a4af6
|
- List all references:
- Change the active branch on a bare repository
git symbolic-ref HEAD
git symbolic-ref HEAD refs/heads/mybranch
|
- Delete a file from history (read about BFG elsewhere):
git clone /foo.git
cd foo/
java --jar bfg.jar -D big_ugly_file.ppt
git reflog expire --expire=now --all && git gc --prune=now
|
§ Branches
§ Making a Subversion working copy into a Git respository
First check out a working copy of Subversion, and create a new
git repository that shares the working copy:
svn co URL/trunk svnGitRepo
cd svnGitRepo
git init
cat > .gitignore <<EOF
.svn/
EOF
git add .
git status
git commit -m "imported from svn"
git log
|
Then I can make a copy of this repository to a detachable disk.
cd /media/USBDISK
git clone /path/svnGitRepo gitOnly # locally
|
Here's a sample remote path:
git clone ssh://host/~/path/svnGitRepo gitOnly # remote
|
Assume that the git-only copy is modified offsite.
cd /media/USBDISK/gitOnly
echo foo > testfile
git add testfile
git commit -m test
git log
|
Later that detachable disk is reconnected and you want the
changes merged with the latest version of the SVN repository.
First update the original SVN working copy, and save the
changes into that Git repository.
cd $HOME/svnGitRepo
svn up
git commit -m "updated from SVN"
|
Thet get the updates from the offsite copy and check them into
SVN.
cd $HOME/svnGitRepo
git pull /media/USBDISK/gitOnly
svn commit -m "updated from Git"
|
Then merge those SVN changes into the offsite Git copy:
cd /media/USBDISK/gitOnly
git pull
|
If the automatic merge fails, then edit the file however you
want. Then, add the conflicted file again, to stage it for
commitment:
git add path/to/merged_file
git commit -m "merged SVN updates"
|
You can also push
commited changes from the client back to
the original repository, but I discourage it. Your changes
will not immediately appear in the original working copy files.
Bill Harlan, 2009-2016
Return to parent directory.