Source From Here
IntroThis tutorial will cover various methods of rewriting and altering Git history. Git uses a few different methods to record changes. We will discuss the strengths and weaknesses of the different methods and give examples of how to work with them. This tutorial discusses some of the most common reasons for overwriting committed snapshots and shows you how to avoid the pitfalls of doing so.
Git's main job is to make sure you never lose a committed change. But it's also designed to give you total control over your development workflow. This includes letting you define exactly what your project history looks like; however, it also creates the potential of losing commits. Git provides its history-rewriting commands under the disclaimer that using them may result in lost content.
Git has several mechanisms for storing history and saving changes. These mechanisms include: Commit --amend, git rebase and git reflog. These options give you powerful work flow customization options. By the end of this tutorial, you'll be familiar with commands that will let you restructure your Git commits, and be able to avoid pitfalls that are commonly encountered when rewriting history.
Changing the Last Commit: git commit --amend
The git commit --amend command is a convenient way to modify the most recent commit. It lets you combine staged changes with the previous commit instead of creating an entirely new commit.
It can also be used to simply edit the previous commit message without changing its snapshot. But, amending does not just alter the most recent commit, it replaces it entirely, meaning the amended commit will be a new entity with its own ref. To Git, it will look like a brand new commit, which is visualized with an asterisk (*) in the diagram below. There are a few common scenarios for using git commit --amend. We'll cover usage examples in the following sections:
Change most recent Git commit message
Let's say you just committed and you made a mistake in your commit log message. Running this command when there is nothing staged lets you edit the previous commit’s message without altering its snapshot. Premature commits happen all the time in the course of your everyday development. It’s easy to forget to stage a file or to format your commit message the wrong way. The --amend flag is a convenient way to fix these minor mistakes:
You can fix your last commit message this way:
Adding the -m option allows you to pass in a new message from the command line without being prompted to open an editor.
Changing committed files
The following example demonstrates a common scenario in Git-based development. Let's say we've edited a few files that we would like to commit in a single snapshot, but then we forget to add one of the files the first time around. Fixing the error is simply a matter of staging the other file and committing with the --amend flag:
The --no-edit flag will allow you to make the amendment to your commit without changing its commit message. The resulting commit will replace the incomplete one, and it will look like we committed the changes to test1.py and test2.py in a single snapshot.
Don’t amend public commits
Amended commits are actually entirely new commits and the previous commit will no longer be on your current branch. This has the same consequences as resetting a public snapshot. Avoid amending a commit that other developers have based their work on. This is a confusing situation for developers to be in and it’s complicated to recover from.
Changing older or multiple commits
To modify older or multiple commits, you can use git rebase to combine a sequence of commits into a new base commit. In standard mode, git rebase allows you to literally rewrite history — automatically applying commits in your current working branch to the passed branch head. Since your new commits will be replacing the old, it's important to not use git rebase on commits that have been pushed public, or it will appear that your project history disappeared.
In these or similar instances where it's important to preserve a clean project history, adding the -i option to git rebase allows you to run rebase interactive. This gives you the opportunity to alter individual commits in the process, rather than moving all commits. You can learn more about interactive rebasing and additional rebase commands on the git rebase page.
Changing committed files
During a rebase, the edit or e command will pause the rebase playback on that commit and allow you to make additional changes with git commit --amend. Git will interrupt the playback and present a message (more):
- Stopped at 5d025d1... formatting
- You can amend the commit now, with
- git commit --amend
- Once you are satisfied with your changes, run
- git rebase --continue
Each regular Git commit will have a log message explaining what happened in the commit. These messages provide valuable insight into the project's history. During a rebase, you can run a few commands on commits to modify commit messages.
Squash commits for a clean history
The s "squash" command is where we see the true utility of rebase. Squash allows you to specify which commits you want to merge into the previous commits. This is what enables a "clean history." During rebase playback, Git will execute the specified rebase command for each commit. In the case of squash commits, Git will open your configured text editor and prompt to combine the specified commit messages. This entire process can be visualized as follows:
Note that the commits modified with a rebase command have a different ID than either of the original commits. Commits marked with pick will have a new ID if the previous commits have been rewritten.
Modern Git hosting solutions like Bitbucket now offer "auto squashing" features upon merge. These features will automatically rebase and squash a branch's commits for you when utilizing the hosted solutions UI. For more info see "Squash commits when merging a Git branch with Bitbucket."
The safety net: git reflog
Reference logs, or "reflogs" are a mechanism Git uses to record updates applied to tips of branches and other commit references. Reflog allows you to go back to commits even though they are not referenced by any branch or tag. After rewriting history, the reflog contains information about the old state of branches and allows you to go back to that state if necessary. Every time your branch tip is updated for any reason (by switching branches, pulling in new changes, rewriting history or simply by adding new commits), a new entry will be added to the reflog. In this section we will take a high level look at the git reflog command and explore some common uses.
Usage
This displays the reflog for the local repository:
Example
To understand git reflog, let's run through an example. You can use git reset to move to any commit relative to HEAD. For example, let's reverse the commit of "add test4" by:
So you can revert your revert this way:
Supplement
* W3Doc - How to Change Older or Multiple Git Commit Messages
* FAQ - How do I make Git use the editor of my choice for commits?
* 30 天精通 Git 版本控管 (16):善用版本日誌 git reflog 追蹤變更軌跡
Find area of rectangle in Python
回覆刪除Program to find area of triangle in Python
Calculate simple interest in Python
Python program to multiply two numbers
Power of a number using recursion in Python
Fibonacci series in Python with recursion
Python program to count the occurrences of a word
Python capitalize first letter of sentence