git

Show only files in a git commit

git show --pretty="format:" --name-only <commit_id>

commit_id can be any tag, or branch as well.

Checkout git branch interactively using fzf

git branch | fzf | xargs git checkout

Remove a/ and b/ prefix from the diffs

git config --global diff.noprefix true

Before

diff --git a/package.json b/package.json
index eb2bf24..5210401 100644
--- a/package.json
+++ b/package.json

After

diff --git package.json package.json
index eb2bf24..5210401 100644
--- package.json
+++ package.json

Useful when you to double-click the filename to select.
Reference

Change URL for the git remote

git remote set-url

git remote set-url origin git@gitserver.com:user/repo_name.git

Delete branch (locally and remotely)

  • To remove a local branch from your machine:

git branch -d {the_local_branch} (use -D instead to force deleting the branch without checking merged status)

  • To remove a remote branch from the server:

git push origin --delete {the_remote_branch}

Resolving rebase conflicts

Sometimes, if you are rebasing after a lot of commits, there may be a lot of conflicts. Sometimes, it is just easier to port your small changes on top of latest master

In such cases, you can get entire good file using

git checkout --ours -- <paths>
# or
git checkout --theirs -- <paths>

Once you have a good base, just port over the delta.

Squash last X commits together

git rebase -i <after-this-commit> and replace "pick" on the second and subsequent commits with "squash" or "fixup

Specify <after-this-commit> as HEAD~5 when you want to squash last 5 commits
Or provide SHA from the git log, if you know specific commit after which you need to squash

See Git Manual for interactive rebase

Discard all local changes

Sometimes I need to discard all the local changes before I can get the latest from the remote.
This happens when my editor has introduced formatting changes that my client does not like (They do not trust auto formatters)
If it was one file, I used to git checkout -- filname but with more than 3 files, this becomes cumbersome.
Turns out git checkout -f is the solution.

If one needs to discard untracked files, then git clean

Use git clean -nfd for dry run if you are unsure, then git clean -fd to do the real clean up.

Local web interface to git

git instaweb : requires lighttpd

Rename master branch

# Rename the old branch locally
git branch -m old-name new-name
# Delete the old branch and push new branch
git push origin :old-name new-name

View contents of a stash without applying it

git stash show -p

If there are multiple stashes, one can pass the stash ID as additional
parameter, like : git stash show -p stash@{0}

Get only subset of files from stash

Sometimes one needs to get only one or a couple of files from the stash, not the entire stash. In such case :

git checkout stash@{0} -- <filename>

Or

git restore -s stash@{0} -- <filename> (Git 2.23 onward i.e. after Aug 2019)

There are more related use-cases and nuances discussed here

Keep your fork up to date with the original

# Create a remote endpoint that points to the original repo
git remote add upstream
https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git
# Get those change in your local repo
git fetch upstream
# Merge from upstream to local
git checkout master
git merge upstream/master
# Publish your updated fork
git push origin master

Nicer git diff viewer

delta

Use git diff without pager

I've been using delta ☝️ as a git diff viewer and have no intention to go back.

But there are times, when you don't want fancy git diff output. e.g. When you need to copy/paste (part of) the changes to share via email/slack/whatever. colored/side-by-side diffs are not useful in such case (Unless you take screenshot, but the receiving party can not copy/paste the code changes on their side)

On such rare occasions, one can use : git --no-pager diff