Advanced Git

Stash manipulation

git stash list

# view specific stash content
git stash show -p stash@{1}

# apply specific stash
git stash apply stash@{1}

Search for commit by message

git log --all --grep='Build 0051'

Abort a git rebase from inside vim during interactive editing


Rebase equivalents to merge

# sync master (remote) -> master (local)
git checkout master
git rebase origin/master

# sync master (local) -> feature-branch (local)
git checkout feature-branch
git rebase master

# sync master (remote) -> feature-branch (local)
git checkout feature-branch
git rebase origin/master

# push local changes to master
git checkout master
git merge feature-branch
git rebase origin/master
git push origin master

# if you want rewrite history
git rebase -i

# conflict
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

# rebase current branch
git rebase -i HEAD~3
git rebase -i 747cf8a07535683c27761db5b85294646167868e

# Then do like this
r new commit message - (first commit on feature)
f - later commits
f - later commits
f - later commits

View only the things that changed in a specific commit

# add --name-only to only see file names that changed

Remove last commit but keep changes unstaged

git reset HEAD^

Blame Line(s) of Code on Someone

git blame -L20,+11 <file>

How to tag an older commit in Git?

git tag -a v1.2 9fceb02 -m "Message here"
# Where 9fceb02 is the beginning part of the commit id.
# You can then push them up using git push --tags origin master

Clone a specific Git branch

git clone -b <branch> <remote_repo>

Stash latest commits in new branch then roll back

git branch newbranch

# Go back 3 commits. You *will* lose uncommitted work.*1
git reset --hard HEAD~3
git push -f

Clear files from git cache incase your .gitignore is acting up

# Make sure you save this file elsewhere it will be deleted!!!
git rm -r --cached somefile.json

Rebase last N commits

# Interactive mode make sure EDITOR=vim

# N is the number of commits before HEAD
git rebase -i HEAD~N

# Use the commit number right before the commit you want the rebase to start at
git rebase -i <commit-number>

Rebase vs Squash

# Both produce a "squashed" commit but they serve different purposes
git rebase --interactive
git merge --squash

Reset or revert a specific file to a specific revision

# Reverts to commit #abcde
git checkout abcde file/to/restore

# Reverts to HEAD
git checkout -- file/to/restore

Fetch remote branch

git fetch <remote> <rbranch>:<lbranch> 
git checkout <lbranch>

Delete remote branch

git push origin --delete <branchName>
# OR
git push origin :<branchName>

Merge two repos into one new one

# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init

# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
dir > deleteme.txt
git add .
git commit -m "Initial dummy commit"

# Add a remote for and fetch the old repo
git remote add -f old_a <OldA repo URL>

# Merge the files from old_a/master into new/master
git merge old_a/master --allow-unrelated-histories

# Clean up our dummy file because we don't need it any more
git rm .\deleteme.txt
git commit -m "Clean up initial file"

# Move the old_a repo files and folders into a subdirectory so they don't collide with the other repo coming later
mkdir old_a
dir -exclude old_a | %{git mv $_.Name old_a}

# Commit the move
git commit -m "Move old_a files into subdir"

# Do the same thing for old_b
git remote add -f old_b <OldB repo URL>
git merge old_b/master --allow-unrelated-histories
mkdir old_b
dir –exclude old_a,old_b | %{git mv $_.Name old_b}
git commit -m "Move old_b files into subdir"

Step through changes to be staged

git add -p

What do the all the options for "git add -p" do?

Stage this hunk [y,n,q,a,d,/,s,e,?]? ?
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk nor any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk nor any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

Diff name only

git diff --name-only file/one file/two

Reset, Checkout, & Revert

git reset

git checkout

git revert