Difference between working directory/stage/HEAD
Shows the changes between the working directory and the index. This shows what has been changed, but is not staged for a commit.
git diff --cached
Shows the changes between the index and the HEAD (which is the last commit on this branch). This shows what has been added to the index and staged for a commit.
git diff HEAD
Shows all the changes between the working directory and HEAD (which includes changes in the index). This shows all the changes since the last commit, whether or not they have been staged for commit or not.
Modify commit history: edit/split/merge commits
Do not modify commits that have already been pushed! Unimaginable nasty things can happen!
There is a guide to splitting commits in the rebase manual. The quick summary is:
- Perform an interactive rebase including the target commit
git rebase -i "<commit-to-split>^" branch) and mark it to be edited. Note that double quotes are required in Windows, otherwise the caret symbol will be interpreted by cmd.exe by escaping the following character. You can also specify the commit before the one you want to edit, this time without the caret:
git rebase -i <the-commit-before> branch
- When the rebase reaches that commit, use
git reset "HEAD^"to reset to before the commit, but keep your work tree intact.
- Incrementally add changes and commit them, making as many commits as
add -pcan be useful to add only some of the changes in a given file. Use
commit -c ORIG_HEADif you want to re-use the original commit message for a certain commit.
- You can also
git commit --amendin order to modify a commit, otherwise new commits will be created.
- If you want to test what you're committing (good idea!)
git stashto hide away the part you haven't committed (or
stash --keep-indexbefore you even commit it), test, then
git stash popto return the rest to the work tree. Keep making commits until you get all modifications committed, i.e. have a clean work tree.
- You can also abort your rebase if you messed things up
git rebase --abort
git rebase --continueto proceed applying the commits after the now-split commit.
Based on: http://stackoverflow.com/a/4307158
Restoring lost commits
Assuming you ran
git reset --hard HEAD^ or just messed with rebasing
causing you to lose a commit or more. Don't panic. Git should still have
your commits in the data store until the next garbage collection cleans
it up, unless you ran
So your commit(s) doesn't show up when you run
git log, you should
see them when running
git flog. Identify in the flog the commit you
want to switch to and run:
git merge <commit-hash>
Show file at specified revision
git show 2c624a9:a.txt git show HEAD~3:a.txt git show "HEAD^":a.txt