Saturday, January 23, 2021

Git cheat sheet


Clone git repo

git clone https://github.com/user/project.git

git clone ssh://git@github.com/user/project.git


Pull

# update (fetch) (from) remote tracking (upstream) and merge into current branch:

git pull

# update from origin:

git pull origin

# update from origin and merge remote branch1 into current branch:

git pull origin branch1

# or:

git fetch origin

git merge origin/branch1

# with no param updates HEAD of remote repository; defined by git-config:

# branch.branch1.remote

# branch.branch1.merge


Show branches

# only local:

git branch

git branch -l

# all including remotes:

git branch -a

git branch -r

# remotes only:

git branch -a | grep remotes/

git branch -a | findstr remotes/


Switch to another git branch

git checkout origin/branch1

# checkout and set track (tracking == new --set-upstream-to):

git checkout -t origin/branch1

# switch to and reset (-B) local branch (based on source branch) (or create if it does not exist):

git checkout -B branch1 origin/branch1

# since git version 2.23.0:

git switch branch1 origin/branch1


Create/Clone branch from another branch and switch into it

# -b = create and checkout new branch (optionally: --track, --no-track)

git checkout -b branch1 origin/master^0 --

More at StackOverflow


Push new local branch to remote

git push origin refs/heads/branch1:branch1 --set-upstream

git push origin refs/heads/branch1:branch1 -u


Merge branch1 to master

git checkout origin/master

git merge origin/branch1

resolve possible conflicts (git-add):

# -f = force, -A = --no-ignore-removal = index+working tree, -- = separate CLI opts from file list

git add -A -f -- src/resolved-conflict.sh

commit resolved changes (git-commit):

# -F = message in file, -- = no more arguments as options

git commit -F C:\git\project1\.git\MERGE_MSG --

push to remote (git-push):

git push origin refs/heads/master:master

# Merge remote branch1 into current branch:
git pull origin branch1


Push
git push -u origin branch1
# no param => use current branch's "remote"—the first half of its tracking info

# push to other name :
git push -u origin experiment:feature,
# this will push local experiment branch to origin feature branch, and
# then --set-upstream-to origin/feature

Rebase

Never rebase publicly used branches

git rebase

git rebase --interactive

git rebase -i

git rebase --onto

See more about Rebase


Delete branch

# delete local:

git branch -d branch1

# delete remote:

git push origin --delete origin/branch1

# prune = delete all local branches without their remote

git fetch -p


Revert file

# undo/revert local changes:

git reset --hard

git stash

git reset HEAD file1.txt # unstage to current commit

git checkout -- file1.txt

git checkout HEAD -- file1.txt

# revert (remove) uncommited file:

git rm --cached -f -- file1.txt

See more at Revert all local changes


Stash

# stash create

git stash save "my stash name"

# stash apply

git stash apply stash@{0}

git stash pop

# stash list

git stash list


Ref log

git reflog show

See more Many undo possibilities


Upstream config
# snippet of git config – refs remotes upstreams :
git config --local –list
# remote and refspec def :
remote.origin.url=https://github.com/username/project.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
# branch master :
branch.master.remote=origin
branch.master.merge=refs/heads/master
# branch X :
branch.X.remote=origin
branch.X.merge=refs/heads/X


Related commands

git fetch upstream

git push -u origin branch1

git remote add origin ssh://...

git config branch.master.remote origin

git config branch.master.merge refs/heads/master

git push origin master


Show current branch name

git symbolic-ref --short HEAD


Show Git remote URL

git config --get remote.origin.url


Check origin fetch and push URL

git remote -v

origin  https://github.com/username/project.git (fetch)

origin  https://github.com/username/project.git (push)


Add remote

git remote add [alias] [url]

git remote add origin https://github.com/user/project.git


Set change remote origin URL to HTTPS or SSH

# set remote origin url to https:

git remote set-url origin https://github.com/username/project.git

# set remote origin url to ssh:

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


Different Git configs

git config --list

git config --global --list

git config --system --list


Push default

git config --global push.default matching

git config --global push.default simple

See default git push

See push default


Global proxy settings

git config --global http.proxy myproxy.com:8080


Global SSL verify

git config --global http.sslVerify "false"

git config --global --unset http.sslVerify


Project specific SSL verify

cd C:\git\my-project

git config http.sslVerify "false"

:: git config --unset http.sslVerify


Set branch upstream

# If you forgot to specify branch upstream during checkout:

git checkout -b branch1 origin/branch1

# you have to set upstream branch later:

git branch --set-upstream-to=origin/branch1

# shortcut for set upstream branch:

git branch -u origin/branch1

# set upstream for other branch:

git branch -u origin/branch1 branch1

# updates git project config as :

branch.X.remote and

branch.X.merge


Relative Refs
# display the grandparent of HEAD:
git show HEAD~2

merge commits => more complicated
merge commints => more parents => more paths to follow

i.e. 3-way merge:
1. parent == main branch you merged into
2. parent == branch mentioned in git merge branchName
~ = follow first parent of merge commit
^ = follow different parent

i.e.: if HEAD is merge commit, display second parent of HEAD by:
git show HEAD^2

Combine into:
git show HEAD^2^1
it is: grandparent of HEAD (if merge commit) which is on the second parent.

Examples:
# Only list commits that are parent of the second parent of a merge commit
git log HEAD^2

# Remove the last 3 commits from the current branch
git reset HEAD~3

# Interactively rebase the last 3 commits on the current branch
git rebase -i HEAD~3

# get back before you ran git reset
git checkout HEAD@{1}



Git branch_name vs refs
1. If $GIT_DIR/<refname> exists, that is what you mean (this is usually useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and CHERRY_PICK_HEAD);
2. refs/<refname> if it exists;
3. refs/tags/<refname> if it exists;
4. refs/heads/<refname> if it exists;
5.  refs/remotes/<refname> if it exists;
6. refs/remotes/<refname>/HEAD if it exists.

Long aside: how this all works (read only if sufficiently curious) :


Sources

git branch vs git checkout -b

track remote branch

IntelliJ Idea branches