- git: http://git-scm.com/about
- git: http://git-scm.com/book
- git: http://www.github.com
- git-flow: http://nvie.com/posts/a-successful-git-branching-model/
git help # Also, "git --help {}".
git help {command}
git clone git://github.com/gitster/git.git
Now necessary to include usernames in checkout. So, e.g., to clone from cloud GitHub:
git clone https://<username>@github.com/.../repo.git
,
and from SQMS Enterprise GitHub:
git clone https://<username>@ghe-sqms.fnal.gov/.../repo.git
- Blank lines are ignored, and a pound sign (
#
) can be used for comments. - A simple, literal filename matches a file in any directory with that name.
- A directory name is marked by a trailing slash character, like so/
- A pattern containing shell glob characters (
*
) is expanded as a shell glob pattern, e.g.debug/32bit/*.o
- An initial ! inverts the pattern over the line.
- You may have a gitignore in any directoy in the repository, and files in lower directories override higher directories.
git config --global user.name "John Doe"
git config --global user.email [email protected]
git config --global core.editor vim
git config -l
git config --global alias.show-graph 'log --graph --abbrev-commit --pretty=oneline'
git show-graph
git config --global color.diff true
git config --global color.status true
git config --global color.branch true
git config --global color.interactive true
Perform in the directory you wish to be the root: git init
git add {files} # e.g., "git add ." after "git init". Must commit.
git add {files} # Also to "re-add" after clearing conflicts in a merge!
# tracked: "git add {file}; git commit" == "git commit -a"
git add -u # Add to the index all the changes of files already tracked.
git rm {file} # Also removes the file. Must commit.
git rm --cached {files} # Staged only.
git commit --dry-run # Don't actually perform the commit.
git commit -a # Commit all, also "--all"
git commit {file}
git commit -m "Message" {file}
git commit --amend # Change the top commit
git cherry-pick {commit} # Bring a single commit from another branch.
git revert {commit} # "Remove" a given commit from earlier.
Workflow example: commit a file, then add another file to the same commit:
git commit file1
git add file2
git commit --amend
git checkout {SHA1 hash} # You only need enough of the hash...
git checkout {tag} # Restore to a {tag}.
git checkout master # The master "tag" refers to the last commit.
git checkout {file}
git checkout {SHA1 hash} {file} # Get back a specific version.
git ls-files -d | xargs git checkout -- # Get all accidentally removed files.
git clone git://github.com/gnperdue/GitTutorial.git
git clone git://github.com/tpope/vim-commentary.git # If you like vi...
git remote add origin https://github.com/gnperdue/GitTutorial.git
git push -u origin master
git remote # Show a list of existing remote
git remote -v # Also, --verbose
git remote show origin
git remote rm {reference} # Drop a remote.
git remote rename {old branch} {new branch}
git fetch {repository} # Find the repository name with "git remote".
# This just gets the data. It does not merge!
# Follow with "git merge" - e.g. "git fetch
# origin" followed by "git merge origin"
git fetch --dry-run # Don't perform a fetch, just show what
# *would* have happened.
git pull {repository} # Fetch *and* merge.
Here, ID
is the pull request number.
git fetch upstream pull/ID/head && git checkout FETCH_HEAD && \
git checkout -b test_ID
This gets the pull, checks us out into a 'Detached HEAD', and then puts us onto a test branch.
git fetch --all && git reset --hard origin/master
git write-tree
git show # Examine various objects.
gitk # Graphical representation of the repository.
git status # What is staged and not, what branch are you
# on, how far ahead is the local, etc.
git log # Show the *reachable* commits.
git log --graph --abbrev-commit --pretty=oneline
git ls-files -s
git ls-files --stage
git log -S{string} # "Pickaxe" - search file diff history.
git log --merge --left-right -p
git reflog # Look at the commit history...
git show {sha1} # May use the first N significant characters
git show --pretty=fuller
git rev-parse {sha1}
git commit --amend -m "New message" # ONLY if you haven't pushed yet
# old message will still show in `reflog`
# but not in `log`
Relative Commit Names ^ the penultimate commit (e.g., master^, master^^, etc.) ~ the previous commit in the ancestry chain.
git log --pretty=short --abbrev-commit master~4..master~2
# Since..Until - used for commit ranges.
git symbolic-ref HEAD
git cat-file -p {sha1}
git tag # List available tags.
git tag -l 'v1.2.*' # List only the tags beginning with
# v1.2.{wildcard}.
git tag -a {tag name} # Make an annotated tag.
git tag -s {tag name} # Make a signed tag (with GPG
# credentials).
git tag -m "Message" {tag name} {files}
git push origin {tag} # Apply a tag to the remote server.
git tag -d {tag name} # Delete a tag.
git push origin :{tag name} # Apply deleted tag to the remote.
git show {tag name}
git checkout {tag name} # Check out a tag; end up left in a
# detached HEAD
git checkout -b {branch name} {tag name} # Check out a tag w/o being left in
# detached HEAD
git tag -a {tag name} {hash} -f # update a tag to be forced to point
# at a new hash
git push origin --tags -f # force the new tag onto the server
Example workflow for creating and pushing a tag:
git tag -a R-2_9_0.1 -m "lamp tag for GENIE R-2_9_0 with corrected SVN paths on HepForge"
git push origin --tags
Example workflow for moving a tag:
git tag -a R-2_9_0.1 80000766b216b23c0 -f # point to new commit
git push origin --tags -f
git show <tag-name> # look at a tag (can `show` other stuff too)
Look at remote tags
git ls-remote --tags
git ls-remote
is generally useful. A nice little workflow
git remote -v
git fetch origin
git checkout tags/boffo -b boffo_working
Delete a tag when it has the same name as a branch
git push --delete origin refs/tags/R-2_10_2
git blame {file}
git blame -L {first line},{last line} {file} # Blame over a range.
git branch # Topic branches
git branch -r # Remote branches
git branch -a # Topic and remote branches
More on remote branches
git remote show origin
git checkout --track upstream/<branch name> # track remote branch
git show-branch # Shows head?
git show-branch --more=N # Goes N deep.
git show-branch -r # See remote in detail!
git merge-base {original branch} {dev branch}
git branch {name*} {starting commit - default HEAD} # Does not switch to the
# branch! (*wildcard ok)
get checkout {name} # Switch to the branch.
git checkout -b {name} # Create a branch *and* switch to it.
# This is short-hand for `git branch {x};
# git checkout {name}`
git fetch; git checkout {remote name} # Checkout a remote branch
git checkout {branch} # git checkout -b {branch} for new one
git checkout --track origin/{branch} # follow an existing remote
A useful stackoverflow post on reverting to previous commits is:
http://stackoverflow.com/questions/4114095/revert-to-a-previous-git-commit
Commands:
git checkout -m {branch} # Bring uncommitted changes with you. Watch
# for merge conflict indicators!
git merge {branch} # Remember, you need to be on the branch you
# want changes merged into.
git reset --hard HEAD # Abort a merge and go back to the state right
# before we typed "merge". Careful with dirty
# repos.
git reset --hard ORIG_HEAD # Abort a merge and go back to right before we
# typed merge after the merge is complete.
git merge -s {strategy} {branch} # Careful!
Note, in case of conflicts, if you just want to take the new file, use:
git checkout --theirs FILE/PATH
and the continue with the merge. To just take all the changes on another branch, use
git merge upstream/${BRANCH_NAME} -X theirs
git branch -d {branch} # You cannot delete the current branch. You
# can override safety checks with "-D".
git push origin --delete {branch} # Delete the remote branch.
git merge origin/remote_branch_name # merge a remote branch into current
git checkout --track origin/{branch}
git checkout -b {new name} origin/{branch}
More tracking a remote branch (with the aim of sending it pull requests):
# <user> is the GitHub user name we want to get the `repo` from:
git remote add <user> https://github.com/<user>/<repo>.git
git fetch <user>
git checkout --track <user>/<branch_we_want_to_target> # needed? - prob. no.
git checkout -b <my_branch_name> <user>/<branch_we_want_to_target>
Example workflow ($BRANCH
could be master
or some other branch):
git remote -v
git remote add upstream [email protected]:${USER}/${REPONAME}.git
git remote add upstream https://github.com/${USER}/${REPONAME}.git # alt
git fetch upstream
git merge upstream/${BRANCH}
Note, for cloud vs enterprise resolution, need to add <username>
, e.g.
git remote add upstream https://<username>@github.com/${USER}/${REPONAME}.git
Note, we can have multuple 'upstream' repositories:
git remote add upstream https://github.com/${USER}/${REPONAME}.git # alt
git remote add otherup https://github.com/${OTHERUSER}/${REPONAME}.git
And, if you screw up the origin
git remote rm upstream # or `destination`, etc.
git checkout other_branch the_file # Bring `the_file` from `other_branch`
# in.
git gc # Often will compress snapshots into diffs
# (happens periodically automatically).
git diff # Difference between the working directory
# and the index.
git diff {commit} # Difference between the working directory
# and the given commit.
git diff --cached {commit} # Difference between staged changes and a
# given commit.
git diff {commit1} {commit2} # Difference between two commits.
git diff --M # Detects renames and generates a
# simplified output.
git diff -w {or --ignore-all-space} # Do not consider whitespace changes to be
# significant.
git diff --stat # Add statistics.
git diff --color # Colorize the output.
git diff integration_b master -- src/Algorithm/Makefile
git diff integration_b master -- src/Algorithm/Makefile src/BaryonResonance/Makefile
git diff integration_b master -- `find . -name "Mak*"`
git diff --shortstst integration_b master # just the total number of
# changes
git reset HEAD # Unstage changes, restore.
git reset HEAD^ # Unstage changes, restore to commit just
# before HEAD. (Remove the topmost commit, often
# explicity "--mixed".)
git reset --soft {commit} # Go back to {commit}, but leave index and
# working directory contents unchanged.
git reset --soft HEAD^ # Get another shot at the commit message only
# ("git commit --amend" is better).
git reset --mixed {commit} # Point HEAD to {commit}, modify index contents,
# but leave working directory unchanged.
# Mixed is default!
git reset --hard {commit} # Point HEAD to {commit}, modify index contents
# and working directory.
- ~>
git reset --soft HEAD~N
#N
is a number (e.g. 2) - ~>
git commit -m "new commit message"
# changes will already be staged
Note: if pushing squashed commits will change the history on the remote, you
must put a +
in front of the branch name, e.g.
git push origin +name-of-branch
- ~>
git checkout master && git pull
- ~>
git merge feature_branch
# local work - ~>
git reset origin/master
# back to origin state
Now, all changes are considered as unstaged changed and we can stage and commit them into one or more commits.
H/T https://github.com/wprig/wprig/wiki/How-to-squash-commits
- Make sure your branch is up to date with the master branch (work on the feature branch here).
- Run
git rebase -i master
. - You should see a list of commits, each commit starting with the word "pick". Make sure the first commit says "pick" and change the rest from "pick" to "squash". This will squash each commit into the previous commit, which will continue until every commit is squashed into the first commit.
- Save and close the editor. It will give you the opportunity to change the commit message.
- Save and close the editor again.
- Then you have to force push the final, squashed commit:
git push origin branch -f
.
git rebase {branch} # DON'T rebase commits you've pushed to a public repo!
git rebase -i master~3 # Interacive rebase (whoah!) going back 3 commits.
Put everything into a quick stash and get a clean working area. ("Interrupted Work")
git stash save "message"
Restore (& drop) a stashed state. Git will attempt a merge. (Only pop into a "clean" area!)
git stash pop
"Look" at the stash.
git show-branch stash
Restore the stash but don't drop it from the index.
git stash apply
Drop the stash (so, "pop = apply (followed by) drop").
git stash drop
Convert the stash into a new branch based on the commit at the time the stash was stashed.
git stash branch
List the stashes (that haven't been dropped), stash@{1}
is older than
stash@{0}
.
git stash show
Other:
git stash save "message" --include-untracked
git stash save "message" --all
Pulling upstream changes from the submodule remote.
# go to the submodule directoy
git fetch
git merge origin/master
# go back to main project directory and see what has changed
git diff --submodule
git checkout -b new_branch
git add files
git commit
At this point, master
has been reset:
git checkout master
new_branch
will contain the changes
git checkout new_branch
git push origin new_branch
Two steps:
git fetch
git reset --hard origin/master
Where, of course, master
is the branch you want.
GitHub puts these instructions on the pull request if you look for them, but here they are anyway (mostly as a one-time log of everything working):
git clone [email protected]:GENIEMC/GENIE_2_9_0.git
cd GENIE_2_9_0
git checkout -b igor144-rein_sehgal master
git pull https://github.com/igor144/GENIE_2_9_0.git rein_sehgal
git push origin igor144-rein_sehgal
GitHub goes on to tell you how to merge into master instead of pushing the new branch, but I want to push the new branch...