This page gives some helpful hints and tricks on using git, along with a suggested work-flow, with an explanation of its motivation and details.
It is assumed at this point that you have a passing familiarity with CVS and/or Subversion; and that you have at least obtained a local copy (cloned) of a remote repository.
man git
git help <command>
man git-<command>
.gitconfig
file.--rebase
option is used).git clone <repository-spec> <local-dir>
or
mkdir <local-dir> cd <local-dir> git initor (FNAL Redmine-specific)
rclone [-r <repo>] <project> <local-name>where
rclone
is defined in cet-chg:export:unix-admin/profile.d/rclone.sh
git log [<tree-ish>]
-m
option entirely and an editor (as specified with VISUAL
or EDITOR
) will be started.git status
git mv <old-path> <new-path>
git rm <path>
git add <un-tracked-file>
git add <files>
git commit -m <log-message>
git commit -m <log-message> <files>
git commit -a -m <log-message>
git reset HEAD <file>
gitk
git diff <file>
git diff --cached <file>
git branch <new-branch>
git checkout -b <new-branch>
git checkout <branch>
git cherry -v <branch>
git merge <branch>
git branch -d <branch>OR (if changes have not been completely merged but you're sure you want to delete anyway):
git branch -D <branch>
Assuming you created your local repository with git clone
, there is already one configured remote origin and you will have a local branch for each remote branch that existed at the time of your last pull
or clone
.
git remote -v
git branch -a
git checkout <branch>
git fetch <remote>
git merge <branch>
git pull
git cherry -v
git push
git push --all
mkdir -p <path-to-safe-dir> tar -cf - . | tar -xC <path-to-safe-dir>Disk space is cheap and
rm -rf
is easy. Note that you must copy the entire repository, since all the important information is in the .git
directory tree at the top level.This is a good way quickly to get a clean tree if you want to merge
or rebase
(see below) to import changes from a branch without having to commit your current work.
git stash
git stash pop(pops off the changes and applies them to the current working area) or
git stash applywhich applies the changes but retains them on the stack.
git stash list
git stash clear
Rebasing is changing history, if you think that git stores history. As mentioned above, it doesn't: it saves objects with parent, child and other (eg date, author, etc) information. In a truly distributed environment, the actual history will be different for every repository depending exactly how and when changes were fetched, merged or pushed.
Rebasing is a good way to do a couple of things:
rebase
anything that has already been pushed to a remote repository. Your next push will almost certainly fail (and quite right too).git rebase -i HEAD~5Your configured editor (
VISUAL
or EDITOR
) will be started and contain a list of your last five commits (most recent at the bottom) along with instructions on what to do. Commits can have their log messages reworded; commits can be removed entirely, combined with other commits or re-ordered. If you specified any rewording or squashing, you will be taken to an edit session for the commit message(s) after saving and exiting the current edit session.git rebase -i <branch>
git pull --rebase
or
git fetch <remote> git rebase <remote>/<branch>
Any pull
, merge
, or rebase
operation can result in a conflict during the application of a particular change from the remote branch. Follow the on-screen instructions to resolve problems. This will usually consist of doing a git status
to list conflicts, editing the files and using git add
to mark each conflict resolved. The process must either be allowed to continue by issuing a git rebase --continue
or git merge --continue
command, or the operation can be reverted with --abort
instead of --continue
. If in doubt, copy your repository.
git checkout -b <branch>
git push <remote> <local-branch-name>[:<new-remote-branch-name>]
git tag -am <message> <version>.Note that the
-a
creates an annotated
tag, which is itself a commit with a hash and a commit message. This is the closest analogue to the CVS tag command. Omitting the -a
option will create a, "simple tag" which is actually a branch. In general, you will probably prefer annotated tags with version-branches created explicitly as desired.git push --tags
There are several things that can go wrong with tagging:
-a
option;If you have not pushed tags yet (See above) then the fix is trivial: for the first two cases, remove the erroneous tag with git tag -d <tag>
; for the third, re-tag with git tag -am <mesasge> [<tree-ish>]
. However, if you have already pushed tags, there are wider consequences. For this reason, altering pushed tags is emphatically discouraged: create a new tag. However, since you're going to ignore me and do it anyway, here's how to do what you want without getting into too much of a mess:
cdcvs
directly as the repository user (e.g. p-art
), cd
to the bare repository with cd /cvs/projects/<project>
and then remove the tag with git tag -d <tag>
.git -d <tag>
and then re-pull from the repository. Otherwise, deleted tags will keep re-appearing in the remote repository and/or users will be unable to pull or push to the remote.git reset --soft HEAD^
git commit -a -m <message> -c ORIG_HEADNote that the
-c ORIG_HEAD
clause causes git to use the meta-data from the previous HEAD (author, etc) with the exception of the commit message. Changing the -c
to -C
and omitting the -m
option will cause git to reuse the commit message too.git log --diff-filter=D --summary | less
git checkout <commit>^ -- file
git add --patch <file>
Tig is a command line tool that wraps many Git browse operations (like log, diff, show, status) in a colored text-mode interface based on ncurses. Tig has been written by Jonas Fonseca.
See the full Tig manual for a detailed description.
Tig is available as package from many Linux distributions. On Debian/Ubuntu it is available with the package name tig from the default repositories.
On RHEL-based systems it is available from the additional repository RepoForge.
On OS X it is easily installed via Homebrew:
brew install tig
Many git commands can be piped into tig. When tig is invoked this way, it is in pager mode: output will be colored according to the input format, and colored.
For instance it is possible to pipe the differences of one file like this:
git diff path/to/file.cxx | tig
or see the changes of one revision like this:
git show b204d4c87 | tig
The most important interactive tig commands are:
Tig invoked without any argument spawns a full log view with one line per commit including author, date and log message. Heads of the different branches are clearly indicated. To see a graph view indicating branching graphically (just like git log --oneline --graph), do:
tig --all
A log can be selected with Enter to see the revision changes.
An example of useful application of the log view is interactive cherry-picking: just press 'C' to cherry-pick currently selected commit into your current branch.
Blame view is extremely useful to see which lines were committed by whom. It is an improved version of the standard git blame command with a much clearer and interactive output.
Each line can be selected to display the associated full commit log and diff.
Usage:
tig blame path/to/file.cxx
tig status opens an interactive display to quickly select files to be staged. Move over the file and press 'u' to (un)stage it.
.gitconfig
file¶This file contains global (~/.gitconfig
) or repository-local configuration settings. You can (eg):
git config --global user.name "Chris Green" git config --global user.email <email-address>
See the attached .gitconfig example. Have fun!
Reproduced with permission from the following page: https://cdcvs.fnal.gov/redmine/projects/cet-is-public/wiki/GitTipsAndTri... by