In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
This article is about how to use Git to change history. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
One of the added values at the core of Git is the ability to edit history records. Unlike version control systems that treat historical records as sacred records, in Git, we can modify historical records to suit our needs. This provides us with a lot of powerful tools to weave a good submission history like using refactoring to maintain good software design practices. These tools may be daunting for novices or even experienced Git users, but this guide will help us unravel the mysteries of the powerful git-rebase.
It is worth noting that it is generally recommended that you do not modify the history of common, shared, or stable branches. It is possible to edit the history of feature branches and personal branches, as well as to edit submissions that have not been pushed. After editing the submission, you can use git push-f to force your changes to be pushed to the personal branch or feature branch.
Despite this dire warning, it is worth mentioning that everything mentioned in this guide is a non-destructive operation. In fact, it is quite difficult to lose data permanently in Git. The guide ends with a description of how to correct a mistake.
Set up sandboxie
We don't want to destroy any of your actual version libraries, so we will use a sandboxie version library throughout the guide. Run these commands to get started. one
Git init / tmp/rebase-sandboxcd / tmp/rebase-sandboxgit commit-allow-empty-m "Initial commit"
If you are in trouble, just run rm-rf / tmp/rebase-sandbox and rerun these steps to start over. Each step of this guide can be run on a new sandbox, so there is no need to redo every task.
Fix recent submission
Let's start with something simple: fix your recent submission. Let's add a file to sandboxie and make a mistake.
Echo "Hello wrold!" > greeting.txtgit add greeting.txtgit commit-m "Add greeting.txt"
It is very easy to fix this mistake. We just need to edit the file and submit it with-- amend, like this:
Echo "Hello world!" > greeting.txtgit commit-a-- amend
Specifying-a will automatically temporarily store all files already known to Git (such as those added by Git), while-amend will squash the changes to the most recent submission. Save and exit your editor (you can now modify the submission information if necessary). You can see the repaired submission by running git show.
Commit f5f19fbf6d35b2db37dcac3a55289ff9602e4d00 (HEAD-> master) Author: Drew DeVault Date: Sun Apr 28 11:09:47 2019-0400 Add greeting.txt diff-- git a/greeting.txt b/greeting.txtnew file mode 100644index 0000000.. cd08755While-/ dev/null+++ bUnip greeting.txtbrush @-0rect 0 + 1 @ @ + Hello world! Fix older submissions
-- amend applies only to recent submissions. What if you need to fix an older submission? Let's start by setting sandboxie accordingly:
Echo "Hello!" > greeting.txtgit add greeting.txtgit commit-m "Add greeting.txt" echo "Goodbye world!" > farewell.txtgit add farewell.txtgit commit-m "Add farewell.txt"
It looks as if greeting.txt has lost "world". Let's write a normal submission to solve this problem:
Echo "Hello world!" > greeting.txtgit commit-a-m "fixup greeting.txt"
Now the file looks correct, but our history can be a little better-let's use the new commit to "fixup" the last commit. To do this, we need to introduce a new tool: interactive rebasing. We will edit the last three submissions in this way, so we will run git rebase-I HEAD~3 (- I stands for interactive). This opens the text editor, as follows:
Pick 8d3fc77 Add greeting.txtpick 2a73a77 Add farewell.txtpick 0b9d0bb fixup greeting.txt # Rebase f5f19fb..0b9d0bb onto f5f19fb (3 commands) # # Commands:# p, pick = use commit# f, fixup = like "squash", but discard this commit's log message
This is a rebasing plan, and by editing this file, you can instruct Git on how to edit history. I have reduced the summary to only the details related to the conversion plan, but you can view the complete summary in a text editor.
When we save and close the editor, Git removes all these commits from its history and executes one line at a time. By default, it pick each commit, summons it from the heap and adds it to the branch. If we have not made any edits to this file at all, we will go straight back to the starting point and select each submission as is. Now, we'll use one of my favorite features: fixup. Edit the third line, change the operation from pick to fixup, and move it immediately after the commit we want to "fix":
Pick 8d3fc77 Add greeting.txtfixup 0b9d0bb fixup greeting.txtpick 2a73a77 Add farewell.txt
Tip: we can also abbreviate it only with f to speed up the next time.
Save and exit the editor, and Git will run these commands. We can check the log to verify the results:
$git log-2-- onelinefcff6ae (HEAD-> master) Add farewell.txta479e94 Add greeting.txt flattens multiple submissions into one
At work, when you reach smaller milestones or fix errors in previous submissions, you may find it useful to write a lot of submissions. However, before merging your work into the master branch, it may be useful to "squash" these submissions together to make the history clearer. To do this, we will use the "squash" operation. Let's start by writing a bunch of submissions, and if you want to speed up, just copy and paste these:
Git checkout-b squashfor c in H e l l o,''w or l d; do echo "$c" > > squash.txt git add squash.txt git commit-m "Add'$c'to squash.txt" done
To make a file that says "Hello,world", there are a lot of things to do! Let's start another interactive transformation, flattening them together. Please note that we first checked out a branch to try. So, because we use git rebase-I master for branching, we can quickly base all submissions. Results:
Pick 1e85199 Add 'H'to squash.txtpick fff6631 Add 'e'to squash.txtpick b354c74 Add 'l'to squash.txtpick 04aaf74 Add 'l'to squash.txtpick 9b0f720 Add 'o'to squash.txtpick 66b114d Add','to squash.txtpick dc158cd Add''to squash.txtpick dfcf9d6 Add 'w'to squash.txtpick 7a85f34 Add 'o'to squash.txtpick c275c27 Add 'r'to squash.txtpick a513fd1 Add 'l'to squash.txtpick 6b608ae Add 'd'to squash.txt # Rebase 1af1b46..6b608ae onto 1af1b46 (12 commands) # # Commands:# p Pick = use commit# s, squash = use commit, but meld into previous commit
Tip: your local master branch evolves independently of the remote master branch, and Git stores the remote branch as origin/master. Combined with this technique, git rebase-I origin/master is usually a very convenient way to base all submissions that have not yet been merged upstream!
We will squash all these changes into the first submission. To do this, change each pick operation except the first line to squash, as follows:
Pick 1e85199 Add 'H'to squash.txtsquash fff6631 Add 'e'to squash.txtsquash b354c74 Add 'l'to squash.txtsquash 04aaf74 Add 'l'to squash.txtsquash 9b0f720 Add 'o'to squash.txtsquash 66b114d Add','to squash.txtsquash dc158cd Add','to squash.txtsquash dfcf9d6 Add 'w'to squash.txtsquash 7a85f34 Add 'oo'to squash.txtsquash c275c27 Add 'r'to squash.txtsquash a513fd1 Add 'l'to squash.txtsquash 6b608ae Add 'd'to squash.txt
When you save and close the editor, Git thinks for a moment and then opens the editor again to modify the final submission message. You will see the following:
# This is a combination of 12 commits.# This is the 1st commit message: Add 'H'to squash.txt # This is the commit message # 2: Add 'e'to squash.txt # This is the commit message # 3: Add 'l'to squash.txt # This is the commit message # 4: Add 'l'to squash.txt # This is the commit message # 5: Add 'o'to squash.txt # This is the commit message # 6: Add' 'to squash.txt # This is the commit message # 7: Add' to squash.txt # This is the commit message # 8: Add 'w'to squash.txt # This is the commit message # 9: Add 'o'to squash.txt # This is the commit message # 10: Add 'r'to squash.txt # This is the commit message # 11: Add'l 'to squash.txt # This is the commit message # 12: Add 'd'to squash.txt # Please enter the commit message for your changes. Lines starting# with'# 'will be ignored, and an empty message aborts the commit.## Date: Sun Apr 28 14:21:56 2019-0400 interactive rebase in progress; onto 1af1b46# Last commands done (12 commands done): # squash a513fd1 Add'l 'to squash.txt# squash 6b608ae Add 'd'to squash.txt# No commands remaining.# You are currently rebasing branch' squash' on '1af1b46'.## Changes to be committed:# new file: squash.txt#
By default, this is a combination of all submitted messages to be squashed, but keeping them like this is certainly not what you want. However, the old submission message can be useful when writing a new submission message, so put it here for reference.
Tip: the "fixup" command you learned about in the previous section can also be used for this purpose, but it discards flattened submission messages.
Let's delete everything and replace it with a better submit message, as follows:
Add squash.txt with contents "Hello, world" # Please enter the commit message for your changes. Lines starting# with'# 'will be ignored, and an empty message aborts the commit.## Date: Sun Apr 28 14:21:56 2019-0400 interactive rebase in progress; onto 1af1b46# Last commands done (12 commands done): # squash a513fd1 Add'l 'to squash.txt# squash 6b608ae Add 'd'to squash.txt# No commands remaining.# You are currently rebasing branch' squash' on '1af1b46'.## Changes to be committed:# new file: squash.txt#
Save and exit the editor, then check your Git log, successful!
Commit c785f476c7dff76f21ce2cad7c51cf2af00a44b6 (HEAD-> squash) Author: Drew DeVaultDate: Sun Apr 28 14:21:56 2019-0400 Add squash.txt with contents "Hello, world"
Before continuing, let's pull our changes into the master branch and get rid of the draft. We can use git rebase like git merge, but it avoids creating merge commits:
Git checkout mastergit rebase squashgit branch-D squash
Unless we are actually merging unrelated historical records, we usually want to avoid using git merge. If you have two different branches, git merge is useful for recording when they merge. In the normal working process, changing the base is usually more appropriate.
Split a submission into multiple
Sometimes the opposite problem occurs: a submission is too large. Let's take a look at splitting them. This time, let's write some actual code. Start with a simple C program 2 (you can still copy and paste this code snippet into your shell to do this quickly):
Cat + + const char * get_name () {+ static char buf (); + scanf ("% s", buf); + return buf;+} + int main (int argc, char * argv []) {+ printf ("What's your name?"); + const char * name = get_name (); + printf ("Hello,% s!\ n", name); return 0;} Stage this hunk
Git only provides you with a "chunk" (that is, a single change) to commit. However, this is too big, so let's use the s command to split this "chunk" into smaller parts.
Split into 2 hunks.@@-1 + 1Magne9 @ @ + # include + + const char * get_name () {+ static char buf [128i]; + scanf ("% s", buf); + return buf;+} + int main (int argc, char * argv []) {Stage this hunk [yLomagle pencycline]?
Tip: if you are curious about other options, please press? Summary display.
This chunk looks better: a single, independent change. Let's press y to answer the question (and temporarily save that "chunk"), then press Q to "exit" the interactive session and continue with the submission. The editor pops up and asks for the appropriate submission message.
Add get_name function to C program # Please enter the commit message for your changes. Lines starting# with'# 'will be ignored, and an empty message aborts the commit.## interactive rebase in progress; onto c785f47# Last commands done (2 commands done): # pick 237b246 Add C program skeleton# edit b3f188b Flesh out C program# No commands remaining.# You are currently splitting a commit while rebasing branch' master' on 'c785f47'.## Changes to be committed:# modified: main.c## Changes not staged for commit:# modified: main.c#
Save and close the editor, and then we make a second commit. We can do another interactive commit, but since we only want to include the remaining changes in this commit, we will do the following:
Git commit-a-m "Prompt user for their name" git rebase-- continue
The last command tells Git that we have finished editing this submission and continue with the next change base command. That's it! Run git log to see the results of your labor:
$git log-3-- onelinefe19cc3 (HEAD-> master) Prompt user for their name659a489 Add get_name function to C program237b246 Add C program skeleton reorder submission
There's nothing to it. Let's start by setting up a sandbox:
Echo "Goodbye now!" > farewell.txtgit add farewell.txtgit commit-m "Add farewell.txt" echo "Hello there!" > greeting.txtgit add greeting.txtgit commit-m "Add greeting.txt" echo "How're you doing?" > inquiry.txtgit add inquiry.txtgit commit-m "Add inquiry.txt"
The git log should now look like this:
F03baa5 (HEAD-> master) Add inquiry.txta4cebf7 Add greeting.txt90bb015 Add farewell.txt
Obviously, it's all out of order. Let's interactively change the base of the past three submissions to solve this problem. Run git rebase-I HEAD~3, and this rebasing plan will appear:
Pick 90bb015 Add farewell.txtpick a4cebf7 Add greeting.txtpick f03baa5 Add inquiry.txt # Rebase fe19cc3..f03baa5 onto fe19cc3 (3 commands) # # Commands:# p, pick = use commit## These lines can be re-ordered; they are executed from top to bottom.
Now, the solution is simple: just rearrange the lines in the order in which you want the submission to appear. It should look like this:
Pick a4cebf7 Add greeting.txtpick f03baa5 Add inquiry.txtpick 90bb015 Add farewell.txt
Save and close your editor, and Git will do the rest for you. Please note that doing so can lead to conflict in practice, see the following section for help in resolving the conflict.
Git pull-rebase
If you have been doing some commits on branches updated by the upstream (such as the original remote), git pull usually creates a merge commit. In this respect, the default behavior of git pull is equivalent to:
Git fetch origin git merge origin/
Suppose the local branch is configured to track the branch remotely from the original, that is:
$git config branch..remoteorigin$ git config branch..mergerefs/heads/
There is another option, which is usually more useful and makes history clearer: git pull-rebase. Unlike the merge method, this is basically equivalent to the following:
Git fetch origingit rebase origin/
Merging is easier to understand, but if you know how to use git rebase, changing bases can do almost anything you want. If you prefer, you can set it as the default behavior, as follows:
Git config-global pull.rebase true
When you do this, technically, you are applying the process we discussed in the next section. So let's also explain what it means to do this intentionally.
Use git rebase to change the base
Ironically, the Git rebasing feature that I least use is the function that it is named after: the rebasing branch. Suppose you have the following branches:
Amura, master-- master-feature-2
It turns out that feature-2 does not rely on any changes to feature-1, it depends on committing E, so you can use it as a basis to break away from master. Therefore, the solution is:
Git rebase-onto master feature-1 feature-2
The non-interactive rebase performs the default action (pick) 5 for all implicated commits, which simply replays the commit on the master in the feature-2 that is not in the feature-1. Your history now looks like this:
Amura master-> master |\-Gmure-> feature-2\-- Emura Fmuri-> feature-1 to resolve conflicts
The details of resolving merge conflicts are beyond the scope of this guide. Please pay attention to another guide in the future. Assuming that you are familiar with the usual methods of conflict resolution, here is the part specifically applicable to changing bases.
Sometimes, a merge conflict is encountered during a change of base, and you can deal with that conflict just like any other merge conflict. Git will set the conflict flag in the affected file, git status will show the problem you need to resolve, and you can use git add or git rm to mark the file as resolved. However, in the context of git rebase, you should pay attention to two options.
The first is how to complete the conflict resolution. When resolving conflicts caused by git merge, a more appropriate change-base command is git rebase-- continue rather than using a command like git commit. However, there is another option available: git rebase-- skip. This will skip the submission you are working on and it will not be included in the subbase. This is most common when performing non-interactive rebasing, when Git does not realize that the submission it extracted from the "other" branch is an updated version of the submission that conflicts with the submission on the "we" branch.
Give me a hand! I broke it!
There is no doubt that changing the base can be difficult at times. If you make a mistake and lose the required submission, you can use git reflog to save the next day. Running this command will show you each action that changes a reference (that is, branches and tags). Each line shows what your old reference points to, and you can perform git cherry-pick, git checkout, git show, or any other action on Git submissions that you think are missing.
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
We added an empty initial commit to simplify the rest of the tutorial, because changing the base of the initial commit of the version library requires a special command (that is, git rebase-- root). ↩
If you want to compile this program, run cc-o main main.c, and then run. / main to see the results. ↩
In fact, this is a "mixed reset". A "soft reset" (done with git reset-- soft) will temporarily save the changes, so you don't need to git add them again, and you can commit all the changes at once. This is not what we want. We want to selectively temporarily save some of the changes to split the submission. ↩
In fact, it depends on whether the upstream branch itself has changed the base or deleted / flattened some submissions. Git pull-rebase attempts to recover from this situation by using the "replicate point fork-point" mechanism in git rebase and git merge-base to avoid rebasing non-local commits. ↩
In fact, it depends on the version of Git. Until version 2.26.0, the default non-interactive behavior was slightly different from interactive behavior, which was usually not important. ↩
Thank you for reading! This is the end of the article on "how to change history with Git change base". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 205
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.