This is a collection of mostly intermediate-level tips and tutorials I have found since starting to use git.
Perhaps you have a repo with a remote called "origin" but you want to fetch changes from a different repo. You need to add the second repo manually:
-
Add the second repo as a remote called "reponame"
git remote add reponame git@git:wx2_origin # or a repo directory, e.g. /path/to/repo
-
List the remotes it knows about: it should have the original repo and the one you added.
git remote -v
-
Fetch the branch
remote_branch
from reponame and call itlocal_branch
locally. (E.g. bothlocal_branch
andremote_branch
might be calledVERSION_80100
.)git fetch reponame remote_branch:local_branch
Now you can switch to
local_branch
or cherry pick from it. -
You can then pull changes from the remote or push your changes using:
git pull origin # Pull from "origin" git push origin git pull reponame # Pull from "reponame" git push reponame
If you have staged changes using git add
then they stop showing up in git diff
. To see them use:
git diff --cached
Search for commits whose messages match the regexp <foo>
:
git log --grep=<foo>
Search for commits whose patch (changes added or removed) matches the regexp <bar>
:
git log -G<bar>
The -w
option to git show
, git diff
and git blame
ignores
whitespace changes, which can considerably simplify the output.
git checkout -
will switch to the previous branch you were on, so you
can you it to switch between two branches. (This is just like cd -
but for branches instead of directories.)
You can reference a git commit using :/<regexp>
, a regexp search for
the pattern <regexp>
in the commit texts (not just the title) for the
youngest matching commit which is reachable from any ref. Note that
this might be in a different branch, and it will be the newest one if
there are multiple matches. E.g. git show :/IS_NUMBER
. (See git help revisions
.)
To do git bisect on just the first parent, mark the other parents as bad: see https://stackoverflow.com/a/5652323/ for details.
If a commit is too complicated you can split it up and bisect individual chunks: see https://gist.github.com/wisq/0fa021df52a3bd2485ac for details.
(You might find that most of the partial commits don't compile. If so, try to separate out the header file changes, or whatever, as necessary first.)
If you want to take changes from another repo but don't want to add it as a remote you can add changes using patches.
NB The following require the git apply
to be called from the top-level
directory of the destination repo otherwise it will fail silently.
To create a patch:
cd sourcerepo && git format-patch <commit1>..<commit2> > patchfile
To apply a patch:
cd destrepo && git apply patchfile
Do both in one command:
(cd sourcerepo && git format-patch --stdout <commit1>..<commit2>) | (cd destrepo && git apply -)
For uncommitted changes;
(cd sourcerepo && git diff) | (cd destrepo && git apply -)
Use git worktree
.
Perhaps you have commits that you want to push but the most recent one is experimental and you want to hold back on it.
git push origin HEAD^:<branch_name>
In general to push everything up to and including some earlier commit:
git push origin <commit>:<branch_name>
When doing a merge these special filenames become available to git show
and git diff
:
- The common ancestor is
:1:<filename>
- The
HEAD
version is:2:<filename>
- The
MERGE_HEAD
version is:3:<filename>
If you edit a file with conflict markers (>>>>>>>
, etc.) to resolve a
merge conflict but mess it up you can ask git to re-create
it using:
git checkout -m <filename>
To deal with e.g. an undesired merge and push:
- Before doing any of these commands use
git status
to check you haven't got any uncommitted changes. If you have, or in any case, stash them and/or take a backup. - You can use
git reset --hard <ref>
to move the current branch (and HEAD) to point to a different commit<ref>
, in this example (eventually!) the one before the merge. - You can use
git log
to see commit refs for commits on the current branch that you might want to move back to. - Or you can use
git reflog
which shows all the previous commits HEAD has pointed to, which might not be on the current branch (e.g. if you've just done a regrettable rebase or reset). - If you have rewritten history before the origin's HEAD it won't let you push so you need to use
git push -f <origin> <branch>
.
See http://stackoverflow.com/questions/8495103/git-stash-and-pop-shows-file-no-longer-marked-as-moved
git rm --cached file1
Look at these commits, which are the dangling commits (not yet garbage
collected) for ones with a title like
WIP on <somebranch>: <commithash> <commit message>
.
git fsck --no-reflog | awk '/dangling commit/ {print $3}'
This is more pleasant using gitk:
gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )
Then you can use git stash apply <hash>
to apply it (or perhaps git stash store <hash>
to save it).
Set git config option core.sharedRepository to group or all. For gitolite 3 use $UMASK. See https://stackoverflow.com/questions/7086325/setting-umask-in-git-gitolite
Perhaps you're trying to switch branch and git says you can't because a
file has changed, but git diff
doesn't show any differences and git stash
says nothing has changed.
This can happen if the file has a filter on it and its timestamp has changed, and it is different from the version in the repo although the "clean" filter version isn't different. If you're sure then fix using:
git checkout -f <file>
Download git-prompt.sh, if you don't already have it as part of your git distribution, and follow the instructions in the comment at the start.
- Pro Git book website, GitHub page and PDF
- Git for Ages 4 And Up
- Explanation of git remote branches and rejected push error
Every change that git is told about, including "git add" and "git stash", is saved in git. You should be able to recover from most mistakes using "git reflog" and "git show" together with "git reset", "git checkout" or "git cherry-pick".
- Reflog, your safety net
- Recovering lost commits with git reflog and reset
- Use "git reflog" and "git cherry-pick" to restore lost commits
- On undoing, fixing, or removing commits in git in the style of "choose your own adventure"
- "Flight rules" for Git
- Disecting Git's Guts
- Git from the Inside Out essay and talk
- Advanced Git: Graphs, Hashes and Compression, Oh My!
- Git from the bottom up