Skip to content

Instantly share code, notes, and snippets.

@dgoguerra
Last active April 8, 2020 10:45
Show Gist options
  • Save dgoguerra/7786601 to your computer and use it in GitHub Desktop.
Save dgoguerra/7786601 to your computer and use it in GitHub Desktop.
Git general usage notes

Table of contents

## Create a new local branch tracking a remote
$ 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.

## Compare file relative to a commit
$ 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>.

## Modifying commits

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.

Example: squash last local commits into one

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.

Squash all changes of a merge as a single commit

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment