Detached HEAD, Amend, rebase and reset in Git

⭐️ more front-end technology and knowledge, search subscription number JS bacteria subscription

The split header causes the COMMIT to be lost

The split header means that after making a change to the checkout history and committing a COMMIT, the branch is switched back and the commit is discarded. You need to manually create a new branch if you want to keep it.

Viewing the Submission Record

git log --oneline
Copy the code

You can see that there are two commit records

7c53c63 (HEAD -> master) initCopy the code

This is when CHECKOUT goes to the historical version

Note: checking out 'c034a61'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at c034a61 init
Copy the code

The split header now appears, at which point you modify the contents of the file

diff --git a/fdsa b/fdsa
index e69de29..2d7a928 100644
--- a/fdsa
+++ b/fdsa
@@ -0,0 +1 @@
+change file content
(END)
Copy the code

To view the status

HEAD detached at c034a61
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:   fdsa

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

The detached HEAD will be prompted for a modification if you commit the COMMIT

git commit -am 'modify'

[detached HEAD 9a78be9] modify
 1 file changed, 1 insertion(+)
Copy the code

If you branch out at this point, those submissions will be discarded by Git at a later point.

git checkout master

Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  9a78be9 modify

If you want to keep it by creating a new branch, this may be a good time
to do so with:

 git branch <new-branch-name> 9a78be9

Switched to branch 'master'
Copy the code

As prompted, use git branch XXX 9a78be9 to create a branch and keep all the commits

git branch -a

  another
* master
(END)
Copy the code

The HEAD version compares the differences between the two operators

The ^ and ~ operators are used differently when diff commit is performed to check the difference between the current commit and the previous or previous version

git diff HEAD HEAD^
Copy the code

Git diff HEAD^1 git diff HEAD~1 git diff HEAD~1 git diff HEAD~1

git diff HEAD HEAD^^
Copy the code

Git diff HEAD HEAD^1^1 git diff HEAD HEAD~2

Git diff HEAD HEAD^2 That’s wrong, there’s no HEAD^2 you have to write HEAD~2 or HEAD^1^1 🤕

fatal: ambiguous argument 'HEAD^2': unknown revision or path not in the working tree.
Copy the code

Amend does not modify the historical submission information

Git commit –amend The last commit message, amend the last commit message. There is no git commit –amend^, the right thing to do is to use rebase

2842585 (HEAD -> master) add app.js 7c53c63 create file c034a61 initCopy the code

Suppose you need to change the second submission to add main.css, then use rebase’s interactive command:

git rebase -i c034a61
Copy the code

Note that the hash value is the previous commit of the commit to be modified

Pick 7c53c63 Create a file pick 2842585 add app.js# Rebase c034a61.. 2842585 onto c034a61 (2 commands)
#
Copy the code

Select * from ‘pick’ to ‘reword’; select * from ‘pick’;

Reword 7c53c63 Create file pick 2842585 add app.jsCopy the code

Save, and a new window will pop up, at which point you can modify the COMMIT message.

[detached HEAD 9ccb083] add main.css
 Date: Fri Jun 7 12:54:21 2019 +0800
 1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.
Copy the code

A message indicating successful modification is displayed.

c0bf3b1 (HEAD -> master) add app.js
9ccb083 add main.css
c034a61 init
Copy the code

In addition, rebase has many other uses, such as merging history commit:

reword 9ccb083 add main.css
squash c0bf3b1 add app.js
Copy the code

Merge the two Commits and modify the latest commit information

[detached HEAD b46e9cc] init website
 Date: Fri Jun 7 12:54:21 2019 +0800
 1 file changed, 1 insertion(+)
[detached HEAD 209f417] init website
 Date: Fri Jun 7 12:54:21 2019 +0800
 2 files changed, 1 insertion(+)
 create mode 100644 app.js
Successfully rebased and updated refs/heads/master.
Copy the code

The combined effect is as follows:

209f417 (HEAD -> master) init website
c034a61 init
Copy the code

Rebase can merge multiple non-adjacent Commits

If we want to merge multiple commits, they are not right next to each other, but spread out. It is still possible to merge using rebase:

1421dc2 (HEAD -> master) init server app
209f417 init website
c034a61 init
Copy the code

If I have three commits and I need to merge the first one with the latest commit, use rebase:

git rebase -i c034a61

Popup editor:

pick 209f417 init website
pick 1421dc2 init server app
Copy the code

Because the first one is not displayed, you need to add it manually

pick 209f417 init website
pick 1421dc2 init server app
pick c034a61
Copy the code

Then adjust the order:

pick 1421dc2 init server app
squash c034a61
pick 209f417 init website
Copy the code

So c034A61 will merge with init Server app

If there is a conflict, resolve the conflict and then rebase –continue or abandon rebase –abort

Checkout, Clean, and reset rollback

Checkout and reset are both used to restore files, but the difference is that checkout restores the workspace and reset restores the staging area to the workspace.

Suppose this is the case at present:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   read.me

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:   app.js

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

	readme.md

Copy the code

If we are prompted to restore the read.me of the staging area, we need to use reset. If you need to restore the modified workspace file app.js, use checkout; There is also the untraced file readme.md, which requires clean to be used for recovery

Let’s recover one by one:

git clean -f
Copy the code

Start by using the clean command to clear the workspace of untraced files

Removing readme.md
Copy the code

Then use the

git checkout .
Copy the code

Clear the files that have been modified in the workspace

Updated 1 path from the index
Copy the code

Finally, restore files in the staging area:

git reset HEAD .
Copy the code

Once the restore is complete, files in the staging area will become files in the workspace, and you will need to checkout or clean again, depending on whether you are adding files or modifying existing ones

Please pay attention to my subscription number, push technical articles about JS irregularly, only talk about technology not gossip 😊