DEV Community

What is your favourite Git command?

Muna Mohamed on June 30, 2019

I'm curious to know, what is your favourite Git command?

Mine is "git commit --amend", which let's you change your last commit message. I manage to mess up a commit message at least once a day 😅

For the sake of clarity, please include what the git command does so we can all learn from one another! 😄

Collapse
 
alvaromontoro profile image
Alvaro Montoro
git blame

The git blame command shows what revision and author last modified each line of a file.

It can also be used to destroy friendships and create awkward moments at work when the application stops working and you want to check who made the last change to the line of code that breaks everything. Example of a possible conversation:

Steve: Production is down, and I don't know what's happening.
Muna: Did you change anything?
Steve: No! It just started happening all of a sudden.
Muna: There's an error on this line, let me check who made the change with git blame.
Steve: (gulp)
Muna: STEEEEEEEEEEEVE!!!!!

Collapse
 
opencode profile image
Apruzzese Francesco

I use Visual Studio Code addon to have blame output always on the code until I read it!!!!

Collapse
 
karataev profile image
Eugene Karataev

Yep, WebStorm also has this handy feature showing an author and date of change of every line.
I use it all the time 🤓
annotations

Thread Thread
 
zenulabidin profile image
Ali Sherief • Edited

Gitkraken also has blame built-in and will show the author and commit message to left of every line. Easier than using the terminal.

Collapse
 
bhupesh profile image
Bhupesh Varshney 👾

This is ✔️🤣

Collapse
 
elecweb profile image
Elecweb
git stash
git stash pop

for keeping file changes without commit. for example, you're doing your new feature and then bug found on production so you need to switch to new branch for hot fix. you can use git stash to keep your changes on feature branch and when you finish fixing bug you can use git stash pop for get back your file changes

Collapse
 
enzoftware profile image
Enzo Lizama Paredes

This is my favorite too!!

Collapse
 
jdforsythe profile image
Jeremy Forsythe

I always find myself using git stash -u so it stashes new files in addition to changed files

Collapse
 
bjornbreck profile image
Bjorn Breckenridge

git stash apply

Collapse
 
rafaelliendo profile image
Rafael Liendo
git reflog

To recover a deleted branch

Collapse
 
elecweb profile image
Elecweb

This one save my life

Collapse
 
ianwijma profile image
Ian Wijma

I might be wrong. But are branches not just archived when they are "deleted"? At least that's how I learner it. 🤔 Or can jou permanently delete a branch.

Collapse
 
guha profile image
Arghya Guha

Git runs a garbage collector automatically from time to time.
If you delete a branch and the commits on it have never been merged with another branch, they will, eventually, disappear.

Collapse
 
hyftar profile image
Simon Landry

Not just deleted branches, deleted commits also! :)

Collapse
 
ben profile image
Ben Halpern

I like to pull a git reset --hard when I need to start fresh.

Collapse
 
sethbergman profile image
Seth Bergman

I use:

git reset HEAD --hard

My alias is:

grshard

I also have an alias forgit, which is just g.

Collapse
 
manan30 profile image
Manan Joshi

I have aliased it as nuke

Collapse
 
mzaini30 profile image
Zen

Wow g 😂

Collapse
 
msamgan profile image
Mohammed Samgan Khan

I m up for this one.

Collapse
 
codeluggage profile image
Matias • Edited

git checkout -b == make a new branch off of your current branch and switch to it
git branch -m == rename your current branch

Branches are "free" in git. When I have mentored other engineers, the most empowering and liberating moment for them is almost always when they see git as a safety net. That tends to go hand in hand with the realization of how powerful branches are.

Got a nasty rebase coming up? Just git checkout -b with the same branch name first, but with some descriptive naming like -before-rebasing at the end. If things get messed up during the rebase, you can just undo everything and go back to before you started the rebase.

Coworker force pushed a branch you were branched off of, and now you can't pull easily due to conflicts? Rename your branch, then checkout their branch from upstream, and you can take your time and compare and fix it locally between 2 branches instead of in the middle of a pull.

Done some git acrobatics and aren't 100% sure then changes are right, but still want to push them up to remote? Make a new branch off of the remote branch so you have a local copy if anything goes wrong.

Made some large changes that you want to keep, but may be going in the wrong direction? Make a new branch, commit the changes, then go back to the original branch and continue working.

I highly recommend naming branches the same, but appending dashes with more explanatory comments, like -refactor or -test-stubs.

Git is a safety net that let's you relax and not worry about the state of your local folder, and liberally creating tons of branches is the key.

Collapse
 
ybbond profile image
Yohanes Bandung Bondowoso • Edited
git commit --amend --no-edit

is one of my favorite too! I even made an alias for this command.
it is now

git cane

my favorite too is

git rebase --continue

after resolving conflict with nvim

Collapse
 
hamstu profile image
Hamish Macpherson
git nevermind

It's not a real git command, but it's an alias to wipe out any uncommitted changes, new files, etc. Basically gets you back to a clean state (i.e., the the last commit.) I do it all the time! (Warning: there's no going back once you run it though!)

This is how to set it up in your ~/.gitconfig:

[alias]
nevermind = !git reset --hard HEAD && git clean -d -f

Collapse
 
munamohamed94 profile image
Muna Mohamed

Ooo, that's an interesting one! Very fitting alias too, haha 😄! Will have to add that one to the toolbox 👍🏾. Thanks, Hamish!

Collapse
 
hamstu profile image
Hamish Macpherson

Glad you like it Muna! I love the name too, it always matches how I'm feeling when I run it. 😅

Collapse
 
hayderimran7 profile image
Imran Hayder

haha good one :D

Collapse
 
mazentouati profile image
Mazen Touati • Edited

Due to my OCD my favorite is git status and when I'm super anxious I'll add the untracked-files option git status --untracked-files="all"

Collapse
 
jckuhl profile image
Jonathan Kuhl

git status every single time I'm about to commit.

Can't be too careful!

Collapse
 
briwa profile image
briwa • Edited

One of my favorites is git add -p. It does an interactive mode to review and stage changes as chunks as opposed to the whole file. Sometimes I would want to commit all of them, other times I'd like to keep some for the next commit or stash them instead. It's like git diff and git add combined.

Collapse
 
drhyde profile image
David Cantrell • Edited

commit --amend is useful, but I think I have to vote for cherry-pick. It makes trivial what can be a right pain in some other version control systems. And if I can cast two votes, let the second one be for bisect.

My least favourite is commit -a -m "...". It makes it too easy to commit many unrelated changes with an unhelpful message. And of course I use it all the damned time.

Collapse
 
olegthelilfix profile image
Oleg Aleksandrov

git push --force origin master

Collapse
 
ianwijma profile image
Ian Wijma

For when you just want to go home right?

Collapse
 
olegthelilfix profile image
Oleg Aleksandrov

Nope, in case, if I would like to be fired as fast as possible.
Of course before that command I should run a few another command, rm - R . & git add . & git commit -m"init of project".
And probably never be hired again ;))

Collapse
 
rohitshetty profile image
Rohit Shetty
git bisect

Git bisect saved my ass a few times last few weeks. Git bisect helps you find out when a previously unnoticed anomaly was introduced. You mark your current version as bad and some previous commit as good (where you know that anomaly didn't exist) and then Git bisect continues "bisecting" your commit history, you continue to mark the current version as either good or bad, ultimately identifying the commit where this unnoticed then bug was introduced.

This can also be used to identify commit when a certain feature was added too. In short, I find it useful especially working with a codebase that does not have much test coverage.

Collapse
 
pcdevil profile image
Attila Gonda

I am a Terminal user, and I even stage my files from the command line.

The most used and my favourite command is:

git add --patch

With this I can choose what hunk I want to add to the staged status. This is very powerful tool which can be a bit confusing, but just a little bit of practice I really liked when I discovered.

It also helped me to practice TDD because if the dirty file list is huge, it takes too much time to figure out what to add. If you want to do small iterations between commits, this kind of enforces you too!

Collapse
 
moopet profile image
Ben Sinclair

Honestly?

git merge --abort
Collapse
 
ecoupal profile image
ecoupal

git rebase -i

Collapse
 
maskapsiz profile image
maskapsiz

The git bisect command checkouts all versions one by one between two revision until you find the version which is not working.

$ git bisect start
$ git bisect bad # Current version is bad
$ git bisect good v2.6.13-rc2 # v2.6.13-rc2 is known to be good

Collapse
 
benneee_ profile image
Benedict Nkeonye

git checkout-b <name-of-new-sub-branch>

Basically, my most used git command. It creates a new branch off the current branch, it's amazing for new features and hot fixes or just random tests.

Closely followed by git status

Can't be too careful...

Collapse
 
eperedo profile image
Eduardo P. Rivero
git stash save "i am totally not to forget this changes"
git commit --amend -m "Previous name was too awful I need to change it"
Collapse
 
jckuhl profile image
Jonathan Kuhl

git init

New day, new project, woot woot.

Collapse
 
hozefaj profile image
Hozefa

For me git reset --soft HEAD 1, I have a git alias for this git undo. This is particularly useful for me when I want to fix small mistakes in committed files, without adding a new commit.

Also, git reflog. Very useful to get info about commits from deleted branches.

Collapse
 
kkm000 profile image
Cy "kkm" K'Nelson

HEAD~1, you missed the tilde. Also, --soft and 1 are the defaults, and @ can be used as a shorthand for HEAD when it's part of a relative graph distance expression, so it's simply

git reset @~

undo is still shorter : )

Collapse
 
alexanderalemayhu profile image
Alexander Alemayhu

Amend is nice, I do it a lot on a daily basis.

git revert

For some unknown reason running git revert feels good to me 😄 It will basically undo what was done for the commit(s) specified.

I use it for removing buggy features right before a deployment or just broken code that was accidentally added. For this to work you would need to commit often and group features into their own commits.

Another weird use case is resetting a file. For ex. in one community repository I have a file called upcoming. When an event is upcoming that file is updated and when a event is over the update is reverted so the upcoming file reverts back to the placeholder text There are currently no events planned.... I might be abusing this command but it works for me 😄

Collapse
 
ketoaustin profile image
Hannah (she/her)

git log --follow <file path> shows the commit history for a file. It’s helpful if you are investigating changes over time. 🤓

Collapse
 
peterwitham profile image
Peter Witham

I wish this wasn't true but it's probably

git --reset hard

For when it truly all goes to the fan.

Collapse
 
waylonwalker profile image
Waylon Walker

So dangerous, my heart rate increased just reading it. But it feels so good to clear out a bad idea and start fresh.

Collapse
 
peterwitham profile image
Peter Witham

So true, any time I have had to use it I always stop and ask myself if I am sure.

Collapse
 
waylonwalker profile image
Waylon Walker • Edited

$&*! I have been working on MASTER !

git stash
git checkout -b new_branch
git stash apply
Collapse
 
sebnozzi profile image
Sebastian Nozzi

I learned to love:

git rebase --interactive [branch]

in order to re-shuffle, combine, split or re-word commits.
To re-write (re-create) a cleaner commit-history.

Collapse
 
arandilopez profile image
Arandi López
alias nah="git clean -df && git checkout -- ."
Collapse
 
mihaylov profile image
Petar Petrov

Mine is rebase

git rebase -i Because its like a swiss army knife.

Collapse
 
waylonwalker profile image
Waylon Walker

I nearly always get the direction of this backwards and screw up my repo

Collapse
 
elgordino profile image
Gordon Johnston
git fetch origin branch:branch

Often when changing branches you might do

git checkout branch
git pull

Which is fine, but if your local 'branch' is way behind origin then this can result in a lot of filesystem thrashing

If you do

git fetch origin branch:branch
git checkout branch

Then you will checkout in to a branch that has already been fast forwarded, avoiding all the thrashing.

Collapse
 
robertobutti profile image
Roberto B.
git commit -m "adding a feature" .

It means that I almost completed a feature 🚀🚀🚀

Collapse
 
raisaugat profile image
Saugat Rai

I like "git checkout - " which let you checkout to previous branch.

Collapse
 
kkm000 profile image
Cy "kkm" K'Nelson • Edited

I'm using surprisingly few every day, I realized, and most of them have been already mentioned. Okay, I have a couple tricks up the sleeve. And I'll name my favorite command later. A bit of suspense, ok?

#1. Make your common command short

git config --edit [--global]

This sounds mundane, but look how far you can get with it:

[alias]
  b  = branch
  bb = branch --all
  bv = branch -vv
  co = checkout
  d  = diff
  dd = diff --staged
  lg = log --graph --format='%C(142)%h %C(36)%ad%C(auto)%d %s' --date=format:%y%m%d
  s  = status --short --branch
  ss = status --no-short
  w  = show
[pull]
  rebase = true
[rerere]
  enabled = true
[rebase]
  autosquash = true
[push]
  followTags = true
[grep]
  lineNumber = true
  patternType = perl
[completion]
  commands = ls-files ls-remote ls-tree rev-parse -citool -gui -gitk -request-pull -send-email -shortlog -whatchanged -credential-gcloud.sh

Besides aliases, I am including a few often missed great defaults to other common commands. YMMV, of course, but I'll go over them, in this and next sections.

  • pull.rebase = true: If you are working through a pull request workflow, you want your commits stay on top of the source branch. You may get conflicts on a pull, but if you do, this means you will get them anyway when sending a PR, so this only saves you same embarrassment. But once you resolved them and then continue on your branch...
  • rerere.enabled = true (for "REcord REbase REsolution" or something like that) is the best thing since bottled beer! Without it, on another pull you'll get the same conflicts. With it, Git remembers how you resolved them, and applies the recorded resolution. Don't see them bastards again!
  • completion.commands = ...: hide/show what you get after a 'git <TAB>'. Those with the '-' are hidden from the default set. Those without are added if normally hidden. And since a package so helpfully decided to put 'git-credential-gcloud.sh' on the PATH, why would I want a non-command 'credential-gcloud.sh' in the completion list? Hide it! If you use "lower-level" commands, like ls-files or ls-remote, expose them to autocompletion! Note: This is new in 2.20, broken in 2.21, and fixed by 2.24.
  • push.followTags = true pushes all annotated tags reachable from the commit you're pushing. Might have been the default, but that would break compatibility with the Git past behavior and piss off a lot of graybeards. I'm only 51 years young, and am already pissed off all too easily. YMMV.

And now (...drum roll...) 'git s' is my favorite command. Succinct and readable output..

2. git grep

No-one's favorite? C'mon! Where are all calls to this function in my project? 'git grep PATTERN' runs grep on your worktree files from the current directory and all down below recursively; see man for more. The [grep] settings above add grep switches '-P' and '-n', respectively. Non-Perl regexps are even more 1980's than disco balls!

3. Three future PRs in one branch? Set rebase.autosquash=true

git commit --fixup <committish>

is what you really want. You work on adding three features at once, and, unfortunately, all of them are dependent. You want to send the first in a PR, then the second, then the third--this is the only way to keep PRs smaller and reviewable. Even found yourself doing this?

$ git lg -3
* d0835482 200423 Add flapdoodle enabled by bamboozler
* 28eb1f47 200421 Replace kaboodler with bamboozler
* e0ce67fc 200421 Fix threading to enable use of bamboozler

Now you're working on adding the flapdoodle, but also fixed another threading bug. No biggie. Stage the fix for the top commit first (git add -p, if needed), and amend the top commit (git commit --amend --no-edit). That's a well-known trick. But now commit all the remaining changes, that threading bug that your brand new flapdoodle uncovered, thanks to the bamboozler:

$ git commit -a --fixup e0ce67

After some testing, you fix more of the flapdoodle and commit a fixup, but then... oh no, what an embarrassing comment typo in the threading fix! So you commit another fixup. _Applying a fixup to the previous fixup reduces chances of a conflict, but doesn't eliminate the possibility.

$ git lg -6
* 6c022160 200426 fixup! fixup! Fix threading to enable use of bamboozler
* 6f34aa90 200426 fixup! Add flapdoodle enabled by bamboozler
* e0ce67fc 200426 fixup! Fix threading to enable use of bamboozler
* 6f34aa90 200426 Add flapdoodle enabled by bamboozler
* 28eb1f47 200421 Replace kaboodler with bamboozler
* e0ce67fc 200421 Fix threading to be able to switch to bamboozler
* . . . .  (origin/master)

And now is a magic time! Note that the --autosquash switch is best set your default setting: it affects only fixups, and is required for the fixup magic to work.

$ git rebase -i --autosquash  HEAD~6  # or origin/master.

And, wonderfully, when an editor opens, fixups are already marked to be applied as fixups, no room for error. Just save the script with no changes, and the rebase leaves you with three clean separate commits, each with the original message. Fork a branch off the bottommost one, send a PR, after it's accepted pull the remote master, rebase your branch on it (if you applied reviewer's comments, you'll get conflicts in that commit, but you just 'git rebase --skip' your initial version of the commit; you might get more conflicts because of these changes in the remaining upper commits, which you'll need to resolve), fork another branch from the bottommost commit... You got the idea. Another option is to 'git cherry-pick' the second bottommost commit to a new off-maser branch to sent it for a review.

4. Not Git proper, but git rev-parse...

...can be wrestled into a very powerful command-line parser for complex tools written in bash, with Git-style subcommands and help messages. Since this is not about Git proper, I'll just leave a link to the parser source and a representative tool sourcing and using it. Search for the occurrences of substrings ArgParse and OPT_, and you'll grok it. The first file is well-commented but still ugly when fixes a couple of Git idiosyncrasies, but the second, with the code which uses it... well, I would not marry it either, bit it's still much simpler and readable with the parser than without it. git rev-parse may provide a lot of leverage if you're facing a task of writing a 5K-line-long bash code tool suite for IaC management of a scientific computation cluster in the cloud...

Collapse
 
msfjarvis profile image
Harsh Shandilya

git add -p for me. I often drift off and make a lot of changes while working on a particular problem, this helps me separate out individual changes to create better and more focused commits.

Collapse
 
siriniok profile image
Vladyslav Siriniok • Edited

git add <path> --patch and git rebase master --interactive

The former is for adding specific lines of code to stage, and the latter is for rebasing current branch on top of the master in interactive mode.

Collapse
 
carloswosiak profile image
Carlos Wosiak

I am really liking the new commands of git 2.23.

In my opinion, it was an excellent idea to split git checkout in git switch and git restore.

Collapse
 
wchr profile image
Wachira

I love this git command

$ git stash

It lets me save uncommitted changes so I can do some rebasing, solve a couple of conflicts then get back to my work

$ git stash pop
Collapse
 
exadra37 profile image
Paulo Renato

Not really a git command per se, but once I use the OhMyZSH shell, that have lots of useful alias to git commands, I love the alias gwip and gunwip.

GWIP

$ alias | grep gwip -
gwip='git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign -m "--wip-- [skip ci]"'

This alias allows me to quickly commit everything, tracked and not tracked changes.

How to use

The current state of my branch is:

$ git status
On branch shipfast-on-docker_approov2-kotlin-wip
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    test.dev.to

no changes added to commit (use "git add" and/or "git commit -a")

Using gwip:

$ gwip
[shipfast-on-docker_approov2-kotlin-wip c7a96dd] --wip-- [skip ci]
 2 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 test.dev.to

That results in this git log:

commit c7a96ddbcca0e4ef6d0f9085cd8d420610eccaa7 (HEAD -> shipfast-on-docker_approov2-kotlin-wip)
Author: Paulo Silva <paulos@criticalblue.com>
Date:   Mon Oct 7 15:25:41 2019 +0100

    --wip-- [skip ci]

 README.md   | 2 +-
 test.dev.to | 0
 2 files changed, 1 insertion(+), 1 deletion(-)

So the message --wip-- [skip ci] tells to the CI pipeline to not run for this commit, and at same time the --wip-- part will be used by the alias gunwip to undo what we have done with the gwip.

GUNWIP

$ alias | grep gunwip -                                                                                                                                                                                   
gunwip='git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1'

The gunwip alias will undo any commit where the message contains --wip--, thus will undo what we have done with gwip.

$ gunwip
Unstaged changes after reset:
M   README.md

Leaving us with:

$ git status
On branch shipfast-on-docker_approov2-kotlin-wip
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    test.dev.to

no changes added to commit (use "git add" and/or "git commit -a")

Summary

During my day I use a lot this 2 commands in order to keep progressing in the code until I am finished with what I am doing, thus be able to proper commit the code.

I also push this wip commits upstream to be protected of an hard disk failure. I do this several times a day, and in the end of the day.

Collapse
 
kev_barbe profile image
Kevin Barbe

This is also one of my favorites, my ridiculous alias for this one is gloga, standing for graphical log all (branches).

Collapse
 
geraalcantara profile image
Gerardo Alcantara

Mine is a "git command combo".

git remote add old-project ../old-project
git fetch old-project
git checkout -b feature/merge-old-project
git merge -S --allow-unrelated-histories old-project/master
git push origin feature/merge-old-project
git remote rm old-project

Merging 2 Git Repositories With History

🐒 Dance

Collapse
 
pavelloz profile image
Paweł Kowalski • Edited

git fetch --prune

To cleanup old local branches.

git gc

To cleanup unnecessary files and optimize the local repository

Collapse
 
ispirett profile image
Isaac Browne

git merge branch-name lol

Collapse
 
niorad profile image
Antonio Radovcic
git retract --overflow --unprint-errors
git bless --retrograde
git bless --assume-mutable-gnomes
Collapse
 
arrlancore profile image
arrlancores
git add .
git commit -m "fix all"

when I forgot to commit some fixes and to many thing to recall ⚡️

Collapse
 
stephanie profile image
Stephanie Handsteiner • Edited

git stash to save uncommitted changes.
git stash pop to continue working on them, after you had to take a break to work on something more important.

Collapse
 
bam92 profile image
Abel Lifaefi Mbula

git commit -am'text here'

Collapse
 
braulio94 profile image
Braulio Cassule

git status

Love seeing all the file that have not been added to git being displayed in red on GitBash or another command-line tool.

Collapse
 
ankurk91 profile image
Ankur K
git push origin dev -f
Collapse
 
waylonwalker profile image
Waylon Walker

I just learned about

git config --global push.default current

Turns that into

git push -f
Collapse
 
kevinhch profile image
Kevin

git push origin master --force :)

Collapse
 
flexyko profile image
xFlex

Satan ?

Collapse
 
guha profile image
Arghya Guha

git init since it marks the start of a new exciting project, probably 😀

git commit --amend is a personal favorite too.

Collapse
 
waylonwalker profile image
Waylon Walker

ooohh git commit --amend is a good one

Collapse
 
theooliveira profile image
Theo Oliveira • Edited

I know the one I hate. Rebase. I am still learning so I am confused about it's use

Collapse
 
waylonwalker profile image
Waylon Walker • Edited

I almost always get interactive rebase backwards. For some reason -i confuses the heck out of me and I avoid it more than I should.

Though I really like to utilize a rebase with master regularly to make sure I dont get behind.

git fetch --all
git rebase master
Collapse
 
munamohamed94 profile image
Muna Mohamed

You and me both, Theo! A senior dev recommended using Git Fork, which makes using git rebase a lot easier because you can visually see what's going on with the branches and commits. Do check it out!

Collapse
 
twonjee2002 profile image
Adetunji Adegbite

git log —oneline This shows me where I was.

Collapse
 
wizsebastian profile image
WizSebastian

git push 😂😂😂 done the issue

Collapse
 
vdedodev profile image
Vincent Dedo

Rebase. Resolves conflicts, interactive mode squashes commits together, probably does more I haven't looked into. It solves my most common git issues when working in a team.

Collapse
 
yamitrvg12 profile image
yamit villamil

Git stash

Collapse
 
jdforsythe profile image
Jeremy Forsythe

git bisect

Collapse
 
ucavalcante profile image
Ulisses Cavalcante

It's hard to chose but I think it's

git reflog
Collapse
 
waylonwalker profile image
Waylon Walker

I have never touched reflog, what is it?

Collapse
 
kkm000 profile image
Cy "kkm" K'Nelson

A little hands-on tutorial. A ref is any file under .git/refs, and a few well-known others, e.g. .git/HEAD: branch heads, tags, etc. Each of them is a simple one-line file containing either a full SHA, or a name of another ref, called a symbolic ref. And example of a symbolic ref is normally the HEAD: type cat .git/HEAD, and it prints ref: refs/heads/master. It's a ref that is akin to a symlink to another ref. Now do cat .git/refs/heads/master. This is a normal, non-sybolic ref to a SHA.

Every time a ref changes (e.g., when you check out another branch, or detach HEAD by checking out a SHA), the old pointer would be irreversibly lost. For convenience, Git can store the old value in the reflog (reflog can be disabled, but enabled by default in non-bare repos). Git locally keeps a log of previous pointers, with the date of modification. These are kept under .git/logs, and the directory mirrors the structure of that above: HEAD's log is in logs/HEAD, .git/refs/heads/master's log is in .git/logs/refs/heads/master, and so on. Try cat .git/logs/HEAD.

Refs are symbolic names for points in history. Try these command in order (assuming you are on the master branch:
(1) git log -1 --oneline , which is a shorthand for
(2) git log -1 --oneline HEAD, which Git resolves (remember that little HEAD file above?) into
(3) git log -1 --oneline refs/heads/master.
(4) git log -1 --oneline master is also special: Git checks if one of refs/heads/master or refs/tags/master exists (I forgot in which order), and also ends up showing you git log -1 --oneline refs/heads/master. All these log commands yield the same output.

reflog is the command that lets you see the history of these ref changes. Try git reflog (a shorthand for git reflog show HEAD), and git reflog show --all, and you'll grok it at once. `man git-reflog has all the rest you need.

Collapse
 
voquanghoa profile image
Võ Quang Hòa

Mine is open -a sourcetree .

Collapse
 
mcabreradev profile image
Miguelángel Cabrera

git reset --hard

Collapse
 
ulubayam profile image
Gizem Ulubayam

My favorite git commad "git log". Because It's good to see who did what and when. Sometimes I even forget what i am doing. My second favorite is "git status".