mkaz.blog

Git Snippets

A collection of git snippets gathered for my own reference.

Oops! Undo

There are various ways to undo a change or go back to a previous state.

Go back

If you made a commit you want to change, use reset it resets the pointer for the entire repository back to that moment. You can use reset with a hash or ~ back from head. This example would move back two commits:

git reset --hard HEAD~2

The --hard flag is optional, if you leave it off it will only unstage the changes, leaving the diff in your working repository.

Revert Commit(s)

If you have a commit you want to reverse but not change the entire repository back to that point, you can use diff or revert.

git diff SHA..SHA^

The ^ means the hash before, you could also get the diff between two different hashes.

Using git diff shows you the diff of the change, if you want to apply it to your working files pipe into git apply.

git diff SHA..SHA^ | git apply

The git revert command will do the same as above in a single command, it will also commit the change to your local repository, use --no-commit to skip.

git revert SHA

Complete Reset Local to Remote

Give up and try again, reset your local branch to remote.

Pull in the last changes, and then do a hard reset to that branch.

git fetch REMOTE
git reset --hard REMOTE/BRANCH

Query Search Git

Show names of changed files

Use the --name-only flag with git-diff to show the list of files changed:

git diff --name-only

I'll use this with vim to edit a set of files, the following will open in vim all changed files:

vim $(git diff --name-only)

You can also use this for staged files:

vim $(git diff --name-only --staged)

Search By Date

Use git log with --after and --before to search by date, be aware of times to cover the whole day. For example:

git log --after="2020-03-01 00:00" --before="2021-08-31 23:59"

Commit Date

Speaking of dates, you can alter time by specifying the commit date, in case you need to fill a gap or two in your commit streaks.

GIT_AUTHOR_DATE='Fri Jul 26 19:32:10 2013 -0400' GIT_COMMITTER_DATE='Fri Jul 26 19:32:10 2013 -0400' git commit

Remote Repositories

New Remote Tracking Branch

A note to myself to not look up how to create a local branch and set it to track a new remote branch in one command. It takes two.

# Create new local branch
git switch -c limb
 
# Push it up to remote and track
git push --set-upstream origin limb

Checkout Pull Request

If you want to checkout a pull request, likely from someone else to your repository, you can using the PR number and not have to create a new remote to their repository.

git fetch origin pull/64/head:pr64
git switch pr64

Update Fork from Upstream

  1. Pull in latest changes from upstream.
git fetch upstream
  1. Switch to trunk branch on fork.
git switch trunk
  1. Bring fork master up to date
git pull --rebase upstream trunk
  1. Push changes back up to fork remote
git push fork trunk
  1. (optional) Rebase a branch to a tag
git checkout my-branch
git rebase v1.9.1

Fix Merge Conflicts

A quick list on how to fix merge conflicts on your branch, more info on preserve-merges flag from here. The process is to update your local master with latest, merge that code onto your branch, update any conflicts and commit those back to your branch.

git switch master
git pull
git switch branch
git rebase master --preserve-merges

At this point you will see the conflict, git status will show the file(s) in conflict. Resolve the conflict by editing, adding, and then committing.

You can then continue down the line using git rebase --continue until all conflicts are resolved.

To commit your changes upstream, you will need to force push up: git push origin branch -f

Squash Everything

If you want to rebase and collapse a repository down to a single commit, sometimes this is useful when converting a private repo to a public one and you don't want to leak any intermediary files.

git rebase -i --root master

Split a directory to own repository

You can create a new repository out of a sub-directory that already exists in a repository. First, clone the repository that holds the directory.

git clone git@github.com:username/fullrepo

Switch to the repository directory and filter on the directory you want to create the new repository from. The example uses subdir and trunk branch, you can specify your branch name.

git filter-branch --prune-empty --subdirectory-filter subdir trunk

Look at your repository, it should now simply consist of the contents of your directory. You can now switch your remote to be a new repository. So if you created a new repository on github called subdir.

git remote set-url origin git@github.com:username/subdir

Then simply push your changes to your new repository and you're all set.

git push -u origin trunk

Resources