laitimes

Git doesn't just pull and push

author:Attack on Grey

Hello, I'm EarlGrey, who insists on sharing dry goods, and has translated and published technical books such as "Python Programming Without Teachers" and "Python Parallel Computing Handbook".

If my sharing is helpful to you, please follow me and strike up together.

Author: Come out Pikachu

Link: https://juejin.cn/post/7071780876501123085

Preface

Using Git for code versioning has long been a must-have skill for today's development engineers. However, most engineers will only save, pull, and push the most basic things, and they will be helpless when they encounter some commit management problems, or solve them in some inelegant ways.

This article shares useful commands that I have practiced in my development work. These can greatly improve work efficiency and solve many difficult scenarios. The following will introduce the commands, list the application scenarios, and teach the use of hands-on, so that students can learn after reading it.

stash

[Official Documentation] https://git-scm.com/docs/git-stash

[git tutorial] https://www.bookstack.cn/read/git-tutorial/docs-commands-git-stash.md

description

Official explanation: Use git stash when you want to record the current state of your working directory and index, but you want to return a clean working directory. The command will save the local modifications and restore the working directory to match the header commit.

The stash command can store the code that has not yet been committed, making your working directory clean.

Application scenarios

I'm guessing you're thinking: why get clean?

Application scenario: One day you are developing a new requirement in the feature branch, and suddenly the product manager comes to you and says that there is a bug online and must be fixed immediately. At this point, you're halfway through the development of your feature, and you rush to switch to the master branch, and then you'll see the following error:

Git doesn't just pull and push

Because there are currently file changes, you need to commit to keep the workspace clean before you can cut the branch. Due to the urgency of the situation, you have to hurriedly commit up, and the commit information is also casually written as a "temporary code", so the branch commit record leaves a black history... (Real people, real stories, have seen this kind of submission)

command usage

If you learn stash, you don't have to be so embarrassed. All you need to do is:

git stash
           

It's as simple as that, and the code is saved.

When you're done fixing the online problem, switch back to the feature branch, and you just need to restore the code:

git stash apply
           

Related Commands

# 保存当前未commit的代码
git stash

# 保存当前未commit的代码并添加备注
git stash save "备注的内容"

# 列出stash的所有记录
git stash list

# 删除stash的所有记录
git stash clear

# 应用最近一次的stash
git stash apply

# 应用最近一次的stash,随后删除该记录
git stash pop

# 删除最近的一次stash
git stash drop
           

When there are multiple stash, you can specify the action stash, first use the stash list to list all records:

$ git stash list
stash@{0}: WIP on ...
stash@{1}: WIP on ...
stash@{2}: On ...
           

Apply the second record:

$ git stash apply stash@{1}
           

pop,drop 同理。

vscode integration

stash code

Git doesn't just pull and push

Fill in the remarks or enter without entering

Git doesn't just pull and push

The saved stash can be seen in the STASHES menu

Git doesn't just pull and push

Click the small arrow next to the stash record, then click Apply or pop to restore the stash

Git doesn't just pull and push

reset --soft

description

No touching the index file or working tree at all (but resetting the head to as in all modes). This changes all of your changed files to "Changes to Commit".

回退你已提交的 commit,并将 commit 的修改内容放回到暂存区。

Generally, when we use the reset command,

git reset --hard

It is mentioned a lot, and it allows the commit record to be forcibly traced back to a certain node. whereas

git reset --soft

As the name suggests,

--soft

(Soft) In addition to backtracking the node, it also retains the modifications of the node.

Application scenarios

Why do you want to keep the changes when you go back to the node?

Application scenario 1: Sometimes you accidentally commit the content that should not be submitted, and if you want to change it back, you can only commit it again, and there is another "black history".

Application scenario 2: A more standardized team generally requires clear responsibilities and fine granularity for the content of the commit, so as to facilitate subsequent troubleshooting. Modifications that originally belong to two different functions are committed together, which is non-standardized. This time it happened to slip again, and it was committed all at once.

command usage

academic conference

reset --soft

After that, you just need to:

# 恢复最近一次 commit
git reset --soft HEAD^
           

reset --soft

It is equivalent to regret medicine, giving you a chance to change again. For the above scene, you can modify it again and resubmit it to keep a clean commit record.

The above is a commit that has not yet been pushed. This command can also be used for commits that have already been pushed, but when pushed again, you will need to force push due to the differences between the remote and local branches

git push -f

来覆盖被 reset 的 commit。

There is one more thing to note in:

reset --soft

指定 commit 号时,会将该 commit 到最近一次 commit 的所有修改内容全部恢复,而不是只针对该 commit。

Take a chestnut:

commit 记录有 c、b、a。

Git doesn't just pull and push

reset to a.

git reset --soft 1a900ac29eba73ce817bf959f82ffcb0bfa38f75
           

At this point, the HEAD reaches a, and the changes to b and c are back in the staging area.

Git doesn't just pull and push

cherry-pick

description

Given one or more existing commits, apply the changes introduced by each commit, and record a new commit for each commit. This requires your working tree to be cleaned (no modifications committed from scratch).

Copy the committed commit and apply it to the branch

Application scenarios

The commits are all committed, so why copy the new ones?

Scenario 1: Sometimes some optimization requirements of a version are halfway developed, and one of the developed requirements may be temporarily released, or the requirements to be developed may be stuck in the development requirements and put online. At this point, you need to extract the commit and handle it separately.

Scenario 2: Sometimes the code records in the development branch are polluted, resulting in problems with the development branch being merged into the online branch, then you need to pull a clean development branch and copy the commit from the old development branch to the new branch.

command usage

Copy a single one

现在有一条feature分支,commit 记录如下:

Git doesn't just pull and push

You need to copy b to another branch, first copy the commitHash down, and then switch to the master branch.

Git doesn't just pull and push

The most recent record for the current master is A, used

cherry-pick

Apply b to the current branch.

Git doesn't just pull and push

When you're done, take a look at the latest log, and b has been applied to master as the latest commit. You can see that the commitHash is different from the previous one, but the commit time is still the same as before.

Duplicate multiple

The above is a copy of a single commit, let's take a look at it again

cherry-pick

How to operate multiple committs.

  • To transfer multiple submissions at once:
git cherry-pick commit1 commit2
           

上面的命令将 commit1 和 commit2 两个提交应用到当前分支。

  • Multiple sequential commits can also be replicated intervals:
git cherry-pick commit1^..commit2
           

上面的命令将 commit1 到 commit2 这个区间的 commit 都应用到当前分支(包含commit1、commit2),commit1 是最早的提交。

cherry-pick 代码冲突

at

cherry-pick

When multiple commits occur, you may encounter code conflicts

cherry-pick

It stops and lets the user decide how to proceed. Let's take a look at how to solve this scenario.

Git doesn't just pull and push

还是 feature 分支,现在需要把 c、d、e 都复制到 master 分支上。 先把起点c和终点e的 commitHash 记下来。

Git doesn't just pull and push

Switch to the master branch and use the interval

cherry-pick

。 You can see that c is copied successfully, and when you get to d, you find that the code conflicts,

cherry-pick

Interrupted. In this case, you need to resolve the code conflict and resubmit it to the staging area.

Git doesn't just pull and push

Then use

cherry-pick --continue

let

cherry-pick

Keep it going. Finally, e is copied in and the whole process is complete.

The above is the complete process, but there may be times when you need to abandon or exit the process after a code conflict:

  • abandon

    cherry-pick

gits cherry-pick --abort
           

Back to the way it was before the operation, as if nothing had happened.

  • quit

    cherry-pick

git cherry-pick --quit
           

Don't go back to the way it was before the operation. i.e. the reservation already

cherry-pick

Succeed in committing, and quit

cherry-pick

process.

revert

description

Given one or more existing commits, revert the changes introduced by the related commits and record some of those new commits. This requires that your working tree is clean (no modifications from the header).

Reverts an existing commit, restores the commit, and generates a restore record.

Application scenarios

Application scenario: One day, the test suddenly told you that there is a problem with the function you developed and launched, and you need to withdraw it immediately, otherwise it will affect the use of the system. At this point, you might want to use reset to roll back, but if you look at the latest commit on the branch and the code of other colleagues, using reset will undo that part of the code as well. Because of the urgency of the situation, and you can't think of a good way, you still use reset willfully, and then ask your colleague to merge his code (colleague hears that he wants to hit someone), so your technical image plummets in the eyes of your colleague.

command usage

revert normal commit

Once you learn to revert, you can save this embarrassing situation right away.

Now the master record looks like this:

Git doesn't just pull and push
git revert 21dcd937fe555f58841b17466a99118deb489212
           

revert 掉自己提交的 commit。

Git doesn't just pull and push

Because revert will generate a new commit record, it will let you edit the commit information, and then save it and exit it when you're done.

Git doesn't just pull and push

Looking at the latest log, a revert record is generated, although your previous commit record will still be kept, but the code content you modified has been undone.

revert merge commits

In git's commit record, there is another type of merge commit, and if you want to revert merge commits, it will be a little different in use.

Git doesn't just pull and push

There are now more merge commits in the master branch.

Git doesn't just pull and push

Using the same revert method, you will find that the command line reports an error.

Why is this happening? It is explained in the official documentation.

It is usually not possible to revert a merge because you don't know which side of the merge should be considered the mainline. This option specifies the parent number of the main line (starting at 1) and allows revert to reverse the change relative to the specified parent number

My understanding is that the merge commit is the intersection of the two branches, and git doesn't know which branch needs to be undone, and needs to add the parameter -m to specify the mainline branch, keeping the code of the mainline branch, and the other is undone.

-m should be followed by a parent number to identify the "mainline", and 1 is generally used to keep the main branch code.

git revert -m 1 <commitHash>
           

After revert merges commits, merging branches again becomes invalid

In the above scenario, after the master branch reverts and commits it, then switches to the feature branch to fix the bugs, and then merges to the master branch, you will find that the modifications that were previously reverted have not been merged again.

Because after using revert, the commit of the feature branch will still be kept in the record of the master branch, and when you merge it again, git will judge that there is the same commitHash, and ignore the relevant commit modifications.

At this point, you need to revert the merge commit of the previous revert, which is a bit awkward, so let's look at the operation.

Git doesn't just pull and push

Now the master's record looks like this.

Git doesn't just pull and push

Use revert again, and the changes that were previously reverted will come back.

reflog

description

This command manages the information recorded in the replay.

If it is said

reset --soft

It's a regret drug, then the reflog is a strong regret drug. It records all commit operations, making it easy to retrieve records after incorrect operations.

Application scenarios

Application scenario: One day, you are dazzled and find that you have committed code in someone else's branch and pushed it to the remote branch, and then you want to use it because the branch only has your latest commit

reset --hard

,结果紧张不小心记错了 commitHash,reset 过头,把同事的 commit 搞没了。 没办法,

reset --hard

It's a forced fallback, and I can't find the commitHash, so I can only ask my colleague to push it again from the local branch (my colleague's fist is hard in an instant, why are you again). As a result, your technical image plummeted again.

command usage

Git doesn't just pull and push

The branch record is as above, and you want to reset to b.

Git doesn't just pull and push

The misoperation reset is too much, B is gone, and only A is left in the latest one.

Git doesn't just pull and push

This is the case

git reflog

Review the history and make a note of the commitHash that was incorrectly committed.

Git doesn't just pull and push

Reset it back again, and you'll find that B is back.

Set up Git short commands

For someone like me who likes to type commands instead of graphical tools, setting up short commands is a great way to be more efficient. Here are two ways to set up short commands.

Way 1

git config --global alias.ps push
           

Way two

Open the global profile

vim ~/.gitconfig
           

Write content

[alias] 
 co = checkout
 ps = push
 pl = pull
 mer = merge --no-ff
 cp = cherry-pick
           

use

# 等同于 git cherry-pick <commitHash>
git cp <commitHash>
           

summary

This article mainly shares 5 practical Git commands in development and ways to set up short commands.

  • stash

    : Stores temporary code.
  • reset --soft

    : Soft backtracking, which reverts commits while retaining the modified content.
  • cherry-pick

    :复制 commit。
  • revert

    :撤销 commit 的修改内容。
  • reflog

    : Records the historical operations of the commit.

Some of the application scenarios listed in the article are not appropriate, but I just want to make it easier for students to understand, and the most important thing is to understand what the role of commands is.

If you also have some practical Git commands, please feel free to share them in the comment area~

-EDF-

I've seen this in the article, don't forget to click "like" and "watching" in the lower right corner to encourage~

Recommended Click on the title to jump

1. Python project engineering best practices

2. Python can be faster than C!

3. streamlit, a super powerful Python library

4. Douban's C++ classic with a score of 8.9 is free to give!

5. What changes have been made in Python 3.12?

Reply to the keyword "pybook03", receive the electronic version of "Think Python 2e" translated by Attack Grey and his friends reply keyword "Book List 02", and receive the electronic version of 10 Python primers organized by Attack Grey

Tell you more details

Welcome to my circle of friends

👆 Update your thoughts and understandings every day