- Create a new local branch tracking a remote
- Check for changes in remote references
- View changes in a commit
- Working with uncommitted changes
- Compare file relative to a commit
- Delete a remote branch
- Basic tags usage
- Modifying commits
$ git checkout -b <branch> origin/<branch>
Example:
$ git branch -a
* new-features
remotes/origin/HEAD -> origin/master
remotes/origin/new-features
remotes/origin/dev
remotes/origin/master
$ git checkout -b dev origin/dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'
## Check for changes in remote repo
git-fetch
brings your remote references up to date.
$ git fetch -v --all
Fetching origin
From https://<path-to-repo>
070a8ce..79278cf dev -> origin/dev
db57a00..28ba91a master -> origin/master
$ git fetch -v --all
Fetching origin
From https://<path-to-repo>
= [up to date] dev -> origin/dev
= [up to date] master -> origin/master
Specifying a verbose output isn't needed, it just shows up-to-date (not updated) branches too.
git-fetch -v --all
equals to:
$ git remote -v update
## View changes in a commit
To show a commit log with statistics:
$ git log --stat
$ git log --shortstat
$ git log --graph --pretty=oneline --abbrev-commit
To view the files changed in a single commit:
$ git diff-tree --no-commit-id --name-only -r <commit hash>
or, to inspect them:
$ git show <commit hash>
## Working with uncommitted changes
### Resetting files
Using git-reset
the index, working tree and local HEAD can be resetted to a specified state.
To reset the working tree to HEAD, reverting and losing all changes:
$ git reset --hard
To revert a single file with uncommitted changes to its state in the latest commit, checking it out from HEAD:
$ git checkout <file>
### Stashing changes
While making changes in the working directory, its current state can be stashed away to go back to a clean directory, matching the HEAD commit:
$ git stash [save <message>]
The modifications stashed away can be listed:
$ git stash list
stash@{0}: WIP on dev: 6073d51 a commit message
stash@{1}: WIP on master: 23fa95b a commit message
The latest stash created is stash@{0}
, the previous one stash@{1}
and so on. To inspect
the changes made in any of them:
$ git diff stash@{0}
To apply a stash to the working tree:
$ git stash apply [<stash>]
If no <stash>
is given, stash@{0}
is assumed.
To delete a stashed state from the list:
$ git stash drop [<stash>]
If no <stash>
is given, stash@{0}
is assumed.
$ git diff <commit> <path>
$ git difftool <commit> <path>
HEAD can be used to refer to the latest commit, or a branch name to refer to its latest commit.
Examples:
$ git diff d571820d8cb9de7f9bc89befc5743c4488ea66ea file.c
$ git diff HEAD file.c
$ git diff new-features file.c
## Delete a remote branch ([since v1.7.0](http://stackoverflow.com/a/2003515))
$ git push origin --delete <branch>
The branch still needs to be deleted locally:
$ git branch -d <branch>
## Basic tags usage
$ git tag -a <tag> -m <comment> [<commit>]
Once set, the tag can be used instead a commit hash to reference it.
A single tag can be pushed to the repository using git push origin <tag>
,
or all local tags with git push origin --tags
.
To delete a tag both locally and from the remote:
$ git tag -d <tag>
$ git push origin --delete <tag>
The existing tags in a repository can be listed using git tag --list
,
or a single one can be opened with git show <tag>
.
git-rebase
offers a useful way of tidying up the local changes of a repo before pushing it to a remote;
some of its common usages are squashing a bunch of commits into one, reordering commits or editing commit messages.
To rebase all the commits between HEAD
and <commit>
:
$ git rebase --interactive [<commit>]
If <commit>
is omitted, all non-pushed commits are selected.
It is dangerous to rebase already pushed commits. If done, git-push
will
require the --force
flag to overwrite the remote.
Explanation from gitready.com, this is done
via an interactive git-rebase
.
To squash the last 3 commits:
$ git rebase --interactive HEAD~3
pick 01d1124 First commit message
pick 6340aaa Second commit message
pick 30e0ccb Third commit message
# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Then, changing all but the first command to squash
will combine the commits together:
pick 01d1124 First commit message
squash 6340aaa Second commit message
squash 30e0ccb Third commit message
Another editor will pop to change the commit message, and the commits will be successfully squashed.
When merging a branch with commits you wish to see as a single one:
$ git merge --squash <branch to merge>
This will change the working tree as if the merge happened, but not actually commit anything. Then you would need
to git-add
the changes and make a normal commit.
The drawback of this method is that it doesn't create a merge commit, so the branch won't be marked as merged and will be left hanging. Thus, this would make sense to use for example with a work-in-progress branch you were about to delete after merging, with commits you don't want to keep track of.