Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@karakays
Last active May 8, 2021 13:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karakays/1ae2f56ee5a698ff5ae890998b967f95 to your computer and use it in GitHub Desktop.
Save karakays/1ae2f56ee5a698ff5ae890998b967f95 to your computer and use it in GitHub Desktop.
git-workflows

Complex workflows in git

Undoing git rm

$ git status
Changes to be committed:     
deleted:    file

Unstage file
$ git reset -- file

Checkout the copy in the index

$ git checkout -- file

Remove file from commit log but still keep it

$ git rm --cached file

Revert a single file to the version of another branch

$ git checkout origin/develop file

Squash commits with rebase

$ git log 
3abc - HEAD -> feature-Z   
2abc  
1abc  
0abc - develop
$ git rebase -i HEAD~4
# or equivalent  
$ git rebase -i 0abc

Reset with ancestery reference

git log MERGE commit c1 c2

git reset HEAD^1 reset two commits. HEAD points to c2. why?

ancestery references difference?

HEAD~ tilda vs. HEAD^ caret

Delete commits with rebase

$ git log 
3abc - HEAD -> feature-Z   
2abc  
1abc  
0abc - develop
$ git rebase -i HEAD~4
# or equivalent  
$ git rebase -i 0abc

Show files changed by stash

$ git stash show

Show stash contents

$ git stash show -p stash@{3}

File revision history

Show the entire history of file

$ git log -p [file]

See what's changed with the specific commit

$ git show HEAD~2

List branches with (tracking) upstream branch

$ git branch -vv

Argumentless push and pull

Without specifying remote and remote-branch, git pushes whatever branch is tracking to. This can be controlled with push.default config.

$ git checkout -b feature -x
# do some commits inbetween
# initially set up remote tracking branch and push there
$ git push -u origin feature -x
# use tracking branch
$ git push
$ git pull

How to create branch to auto-track branch with same name but not yet created?

Delete remote branch

$ git push origin --delete foo 

or what syntax is this?

$ git push origin :foo 

Updating feature branch

A feature may take several days or even weeks to complete which then causes the feature branch to stay way behind from develop and commits to be scattered around in the history. For the purpose of keeping a clean history, first get latest develop and move the complete feature branch on top of it.

(develop) $ git pull origin develop 
(develop) $ git checkout feature
(feature) $ git rebase develop

After updating the feature branch, squash all feature commits into one and then create a PR.

(feature) $ git rebase -i develop
(feature) $ git push origin feature

Merging branches with tags

It's always commits that gets tagged, not branches. As long as a commit identifier is not changed, the tag is kept in the target branch. See how commits are changed after a branch merge. Merge strategies definitely matter here.

(release/1.2) $ git log 
3abc - HEAD -> release/1.2, tag: v1.2
2abc
1abc
...
(master) $ git merge -no-ff release/1.2

With no fast-forward merge, tag is forwarded to target branch but MERGE_HEAD stays one commit behind due to the new merge commit.

(master) $ git log
4def - Merge commit, HEAD -> master
3abc - tag: v1.2
2abc
1abc

For fast-forward merges, tag is forwarded then there will be no merge commit and exact revision and tag coming from release branch will stay. However, it's not always possible to avoid merge commits if branches differ.

For squash strategy, tags are not merged as the commit has changed in the target branch. merge will not merge tags because a new commit is born in the target branch. However, tag still stays where it is in the release branch. Remember it's always the commits that are tagged. If a commit from a branch itself cannot be merged, then its tag cannot be merged, too.

Checkout to tag

Checking out to a tag results with a detach state because a tag can be reachable by multiple branches (say develop, master etc.) Git has no way to know which branch you are in so it's detached.

$ git checkout version-0.3
HEAD detached at version-0.3

Remove unknown files

Clean working directory by removing untracked files

$ git clean -n
$ git clean -f -d

Fugitive

:Git is akin to :git! but with improvements. :Git can be shortened as :G. :Git blame can be written as :Gblame.

Enter git summary

:G

Operations

 -     |:Git| add
 -     |:Git| reset (staged files)

 cc    |:Gcommit|

 D     |:Gdiff|
 ds    |:Gsdiff|

Load logs into quickfix

:Glog
:Gclog

Load previous revisions of current file into quickfix

:0Glog
:{range}Glog

1. Show revisions to current buffer and load into quickfix

2. Show diff of current commit in quickfix list

:0Glog
:Gdiff

??? Discard changes to current buffer like git checkout -- file

:Gread

Next/previous conflict

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