02 Git Tips & Tricks - lukes8/wiki-notes GitHub Wiki

checkout, detached HEAD state

git checkout origin/devel ... means that you checkout directly with origin remote devel branch which is risky - this can lead to detached HEAD as we detached our local HEAD to remote one. This is not secure way

You can simply prevent or switched from detached HEAD with this command
git checkout -b <your_local_devel_or_different_name_for_branch>

Finally to keep things simple with one command, with this we can simply checkout remote branch and create local copy and switch on it in secure way
git checkout -b devel origin/devel

Git reset, normal, soft and risky hard

HEAD~ or HEAD^ or HEAD~1 means always the same story - parent of child.
This means if Bob has two commits in branch A - B - HEAD then HEAD~ means that parent of our B child/commit is basically A.

git diff HEAD~ ... we can show differences between our current HEAD (child) and HEAD~ (parent)
git diff HEAD~2 ... or we can show diff between our HEAD and 2 parents behind

git reset HEAD~ ... means just return back to parent commit which undo our HEAD to previous state / undo our last commit. It will keep in working area or staging area. So we dont need to worry about that
git reset --soft HEAD~ ... similar like above case just with keeping files in staging area
git reset --hard HEAD~ ... this is so risky, not recommended... it removes last Nth commits permanently so keep that in mind

Git rebase

image

image

Git and reflog

git reflog origin/master
git reflog HEAD

The git reflog command is used for Git to record updates made to the tip of branches. It allows to return to commits even to the ones that are not referenced by any branch or any tag...

How to display if branch has a tag, versioning

git branch --contains tags/<tag>

How to display all git commits, graph format, all commits from origin branches

git log origin

git log --graph origin/master

git log --graph [branchname] 

git log --graph origin/[branchname] # if your local checkout isn't up to date

git shortlog --no-merges --graph --abbrev-commit master..<mybranch>

git log --decorate --oneline --pretty='%h refs: %d message:%s'


How to push tag to remote, when reckon plugin complains

Typical use case when (got from jenkins build):
Reckoned version <tag_version> has already been released.

Background/reason:
Means that we have already newer tag version. It might be caused when we have 2 branches and 1 using 1.123 tag version
and branch 2 using 1.0 tag version. When build branch 2 with reckon plugin then it fails with above message.

First you need to create specific tag for some commit
Then you need just push it to remote via this cmd

git push origin <tag_name>

To checkout to specific tag

git checkout tags/<tag> -b <branch>

To display all tags or branches ordered by date with date field

ascending order
 git tag --sort=creatordate --format="%(refname:strip=2) %09%09 %(creatordate:short)"

desc order from newest to oldest
 git tag --sort=-creatordate --format="%(refname:strip=2) %09%09 %(creatordate:short)"

desc order to see branches from remote origin
git branch --r --sort=-creatordate

How to get git help from cmd

git help
git help push or git push --help ... means open help web page with everything around push command

How to remove commit in specific branch

git reset --hard HEAD~1 ... means commit before head (means you remove commit you are sitting on and reset/return to previous one)
git reset --hard HEAD .. means just display message that you are on the HEAD (git doesnt know where we want to reset current commit)
git reset --hard HEAD~2 ... means commit before head + one commit (other words, please take the commit that is 2 commit 'years' old)
git reset --hard <sha1-commit-id> ... means specific commit


To display all commits between specific tags to review the code changes

It can be useful for eg. if you want to clarify what is on PROD in comparison with DEV environment. Or to make code review on bitbucket with valid PR. As important thing to proof that new changes were confirmed with approvals.

To display all commits between specific tags starting from HEAD that match grep expression (-i ignore case)
todo="find me green"
git log --pretty=format:"%C(yellow)%h %<(40,trunc)%C(green)%d %<(10,trunc)(author: %cn) %Creset   %<(50,trunc)subject:%s %C(blue)%ci"  HEAD...6.0.175 -i --grep="$todo"

To display all commits with colourful and tab delimited and truncated output. 
%<(10,trunc) means that it truncates every string greater than 10 otherwise add some blank spaces to ensure that length string is 10
git log --pretty=format:"%C(yellow)%h %<(40,trunc)%C(green)%d %<(10,trunc)(author: %cn) %Creset   %<(50,trunc)subject:%s %C(blue)%ci"  6.0.190...6.0.175
 
To display all commits between particular tags (including them) in proper order that match only grep string
git log --pretty=format:"%C(yellow)%h %<(40,trunc)%C(green)%d %<(10,trunc)(author: %cn) %Creset   %<(50,trunc)subject:%s %C(blue)%ci"  6.0.190...6.0.175 --grep="TODO_FIND_ME "
 
To display only first 10 commits starting from tag 6.0.190
git log --pretty=format:"%C(yellow)%h %<(40,trunc)%C(green)%d %<(10,trunc)(author: %cn) %Creset   %<(50,trunc)subject:%s"  6.0.190...6.0.175 -10

Git log

Display last 5 commit messages

git log -n 5 --author=Salvador

git log --oneline -n 5 --author=Salvador

Git log, display git logs in graph format - you can see tree of commits, useful

$ git log --oneline --graph

* 53a7dcf (HEAD -> v1.0-branch, tag: v1.0) Version 1.0 commit
* 0a9e448 added files
* bd6903f (release) first commit

Git config

git config --list

git config --list 

git config -l    //list config as shortcut

git config -e    //open config in default editor

git config --get user.name && git config --get user.email

git config --global user.email <youremail> && git config --global user.name <yourname>

How to get the git commit count

https://stackoverflow.com/questions/677436/how-do-i-get-the-git-commit-count

git shortlog

git rev-list --count <revision>

git rev-list --all --count


How to abort current rebase?

If you see that your branch is in rebase state, then you could abort that rebase or skip
git rebase --skip | --abort

This action will return to your last commit from where the rebase started. Keep in mind that your new commits during rebase phase will be lost. In the other hand, if you will push your branch to remote upstream repo, then your commits wont be lost.

How to fix corrupted rebase?

If the action with --abort not proceed success then you need to fix corrupted rebase.

The git tried to remove the folder but it did not succeed. 
You need to move that folder away and try to remove it manually from .git/rebase-merge.
Sometimes you need to kill process with Vim or Vin editor because of process stucked. Then the deletion should work.

How do I create a new branch from a remote branch? To take a remote branch as the basis for your new local branch, you can use the "--track" option: $ git branch --track origin/

git push origin local_branch:remote_branch

How to checkout on specific tag as new branch

$ git checkout tags/v1.0 -b v1.0-branch

Switched to a new branch 'v1.0-branch'

$ git fetch --all --tags

Fetching origin
From git-repository
   98a14be..7a9ad7f  master     -> origin/master
 * [new tag]         v1.0       -> v1.0

$ git log --oneline --graph

Tip: it can be useful when you need to checkout on specific version of app - tag is usually used for version tagging eg. when new version v1.1 is released then the new tag is also created in git as v1.1. With this you have great way how to check your current version (bitbucket, github, etc.)

Bitbucket codereviews

There is the option Code review when you get to Branches.
Trusted base line: this is meant as old commit from previous release ie. from tag 1.1
Current base line: this is meant as current snapshot commit ie. next iteration phase for development from tag 1.2-snapshot

Hint: typical problematic use case

You can use also tags for simple usage. However you can encounter that some of commits were not properly approved by pull requests and so the code review can passed with FAILED status. In this case you have two options:
- you can use trusted base line as some different commit. In best case after the problematic commit you used before
- you can create new branch from problematic commit and then merge your master branch into this branch via pull req. With this approach the code review should be now passed

How to revert commit

If you have some commit in past that is needed to be fixed or reverted, you can use this cmd

$ revert 'YOUR_COMMIT_ID'

A git revert commit really good example

$ touch alpha.html
$ git add . && git commit -m "1st git commit: 1 file"

$ touch beta.html
$ git add . && git commit -m "2nd git commit: 2 files"

$ touch charlie.html
$ git add . && git commit -m "3rd git commit: 3 files"

$ touch delta.html
$ git add . && git commit -m "4th git commit: 4 files"

$ touch edison.html
$ git add . && git commit -m "5th git commit: 5 files"

A call to the git reflog command will show us our current commit history:

$ git reflog
(HEAD -> master)
d846aa8 HEAD@{0}: commit: 5th git commit: 5 files
0c59891 HEAD@{1}: commit: 4th git commit: 4 files
4945db2 HEAD@{2}: commit: 3rd git commit: 3 files
defc4eb HEAD@{3}: commit: 2nd git commit: 2 files
2938ee3 HEAD@{4}: commit: 1st git commit: 1 file

We want to revert the 3rd git commit with charlie file 
$ git revert 4945db2

The git revert command will undo only the changes associated with a specific commit. In this git revert example, the third commit added the charlie.html file. When we revert said Git commit, the only file removed from our repository is charlie.html.

$ ls
alpha.html  beta.html  delta.html  edison.html


Resource: https://www.theserverside.com/tutorial/How-to-git-revert-a-commit-A-simple-undo-changes-example

How to change commit author for one specific commit

We can use rebase option for this purpose. The rebase is great tool that we can use when we need to change some commits in past eg. add some files, change author name, change commit message, or whatever.

Shortly 
git rebase -i <earliercommit>
you will be redirected to rebase settings via Vim or Nano editor. 
you can use edit for commits you want to change insteand of pick
save your file in Vim via :wq
git commit --amend --author="Author Name <[email protected]>"
git rebase --continue

Really good example for use case

git rebase -i <earliercommit>

For example, if your commit history is A-B-C-D-E-F with F as HEAD, and you want to change the author of C and D, then you would...

Specify git rebase -i B (here is an example of what you will see after executing the git rebase -i B command)
if you need to edit A, use git rebase -i --root
Change the lines for both C and D from pick to edit
Exit the editor (for vim, this would be pressing Esc and then typing :wq).
Once the rebase started, it would first pause at C
You would git commit --amend --author="Author Name <[email protected]>"
Then git rebase --continue
It would pause again at D
Then you would git commit --amend --author="Author Name <[email protected]>" again
git rebase --continue
The rebase would complete.
Use git push -f to update your origin with the updated commits.

Resource: https://stackoverflow.com/questions/3042437/how-to-change-the-commit-author-for-one-specific-commit

How to checkout remote branch from somebody else who forked the master branch

git remote add coworker git://path/to/coworkers/repo.git
git fetch coworker
git checkout --track coworker/foo

This will setup a local branch foo, tracking the remote branch coworker/foo. So when your co-worker has made some changes, you can easily pull them:

git checkout foo
git pull

Tip This is useful when an user want to merge his changes to master branch via Pull Request and so we can easily check his branch what he wants to add. With this we can check status of some interested project and so we can learn more about some interested topics/features.

How to get more help info about git when not sure about command

just remember this command - git -h
for eg. we forgot how to rename local branch and so we can use this help that will show us next options how to use that command
git branch -h

How to compare current and previous commit, or how to compare other commits

- LEGEND
HEAD - this is current commit we are working on
@ - this is shortcut for HEAD
@~1 - this is previous commit
@~2 - this is second previous commit
@~1..@ - this is range between HEAD and previous commit
@~2..@ - this is range between HEAD and second previous commit
@~2..@~1 - this is range between previous commit and second previous commit


Examples:
Get compare diff between last commit and previous commit - only list of affected files
git diff --name-status @~1..@

git diff @~1..@~2

Get compare diff between last commit and previous commit - only list of affected files
git diff-tree -r --name-only @~1..@

Get list of affected files for previous commit with highlighted changes
git show @~1 

Get list of affected files for previous commit with highlighted changes
git show --name-only @~1

Get list of file names affected for previous commit
git diff-tree -r --name-only @~1

Get list of file names for previous commit plus their status which means - A as added, M as modified, etc. very useful
git diff-tree -r --name-status @~1

Tip: use these commands for efficient work, just to show last work before HEAD

git show --name-only @~1
git diff-tree -r --name-only @~4..@
git diff-tree -r --name-status @~1
⚠️ **GitHub.com Fallback** ⚠️