Git快速入门-git stash 暂存变更,git reset 撤销commit,git revert 回退远程版本库

Git快速入门系列文章
- Git快速入门-安装配置篇
- Git快速入门-常用命令之独奏篇
- Git快速入门-常用命令之交响乐篇
- Git快速入门-git stash 暂存变更,git reset 撤销commit,git revert 回退远程版本库

注:本文基于git version 2.13.5 版本进行演示

1. 概述

Git入门系列第四篇,基于场景,介绍一些非常实用的Git命令,也许这些命令会让你产生“还有这种操作”的感叹。例如如何把修改暂存起来,留着以后使用?想撤销已提交(commit)到本地版本库的代码该怎么办?撤销已push到远程代码库的代码呢?

2. 如何把修改暂存起来,留着以后使用?

2.1 使用场景

实际开发过程中,我们经常会遇到这样的问题,当我们想把远程仓库的最新代码拉下来时,发现git会提示说我们本地做的修改会被覆盖,建议先commit代码或者stash(暂存)代码。你一定遇到过类似下面这样的提示:

$ git pull origin master
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (4/4), done.
From github.com:flysqrlboy/git-command-tutorials
 * branch            master     -> FETCH_HEAD
   7dd2e09..d7e1e19  master     -> origin/master
Updating 7dd2e09..d7e1e19
error: Your local changes to the following files would be overwritten by merge:
    b.txt
Please commit your changes or stash them before you merge.
Aborting

留意下面两句提示,我们可以有两个选择:commit或stash。

error: Your local changes to the following files would be overwritten by merge:
b.txt
Please commit your changes or stash them before you merge.

如果我们本地的代码修改得差不多了,可以选择commit到本地版本库。但如果我们的修改只是个半成品,我们不想把这样的代码留在提交历史里的话。git stash就能派上用场了。

2.2 git stash 暂存进度

先来看下当前的工作区和暂存区状态:

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

    modified:   a.txt

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:   b.txt

git status 输出中告诉我们,a.txt 和 b.txt 都有修改,a.txt 已加入到暂存区(在Changes to be committed下面),b.txt 的修改则还在工作区中(在Changes not staged for commit下面)。正是因为远程代码库有人更改了b.txt ,才导致本地拉取代码时提示会被覆盖。这里,用git stash 命令保存当前工作进度。

$ git stash
Saved working directory and index state WIP on master: 7dd2e09 add two files a.txt b.txt

运行git stash 之后,再查看工作区状态,会发现之前工作区和暂存区的修改都不见了。

$ git status
On branch master
nothing to commit, working tree clean

2.3 查看进度

查看stash进度用命令git stash list

$ git stash list
stash@{
  
  0}: WIP on master: 7dd2e09 add two files a.txt b
<think>好的,我现在需要帮助用户解决如何回退git add .、git commit --amend和git push这三个操作带来的更改。首,我得回忆一下每个Git命令的作用,以及如何撤销它们。 首,用户执行了git add .,这会将所有修改添加到暂存区。接下来是git commit --amend,这通常用于修改最近一次提交,可能改变了提交信息或内容。最后是git push,将本地的提交推送到远程仓库。现在用户想依次回退这些操作带来的更改,可能需要分步骤处理。 首回退git commit --amend后的提交。根据引用[5],git commit --amend会修改最近的提交,而使用git reset HEAD^可以回退到上一个提交。但要注意,amend后的提交实际上替换了原来的提交,所以需要找到amend之前的提交哈希值,可能需要用git reflog来找回原来的HEAD位置。 接下来,撤销git add .的操作。根据引用[4],git restore --staged .可以取消所有暂存的文件,恢复它们到工作区。或者使用git reset HEAD .也可以达到类似效果。这一步应该放在回退commit之后,因为如果撤销add,可能影响后续的commit撤销操作。 然后是处理已经push到远程仓库的amend提交。因为amend改变了提交历史,直接push可能需要强制推送(git push -f),但用户现在需要撤销这个推送。这时需要将本地分支回退到amend之前的状态,然后强制推送到远程,覆盖历史。根据引用[2]和引用[5],强制推送有风险,需确保团队其他成员知道这次更改,避免协作问题。 现在需要考虑操作顺序。用户已经执行了add、amend和push,现在需要逆向操作。正确的顺序应该是回退本地的amend提交,然后撤销add,最后处理远程仓库的强制推送撤销。或者是否需要处理远程仓库,再处理本地? 可能步骤是: 1. 本地使用git reflog找到amend之前的提交,reset到该提交。 2. 撤销git add .的影响,可能使用git restore --staged .。 3. 强制推送本地回退后的状态到远程,覆盖远程的amend提交,使用git push -f。 但需要详细检查每个步骤是否正确,以及是否有遗漏的情况。例如,在amend之后,是否还有未提交的修改?如果amend后用户又做了其他修改,可能需要额外处理。 另外,引用[2]提到了git revert,但revert会生成新的提交来撤销更改,这可能不适合用户的需求,因为用户想要完全回退到之前的状态,而不是添加新的撤销提交。因此,使用reset可能更合适。 总结步骤: 1. 回退本地的amend提交:使用git reflog找到amend之前的提交哈希,然后git reset --hard <commit-id>。 2. 撤销git add .:在reset之后,可能工作区已经恢复,但如果有暂存的文件,可能需要git restore --staged .。 3. 强制推送到远程git push -f origin <branch-name>,覆盖远程的历史。 需要注意的是,强制推送会影响其他协作者,所以需要谨慎操作。此外,确保在操作前备份当前状态,防止数据丢失。 可能用户的问题在于如何找到amend之前的提交哈希,这时候git reflog就非常有用,可以查看操作历史,找到amend之前的HEAD位置。例如,在reflog中会有类似这样的记录:HEAD@{1}: commit (amend): ...,而之前的提交就是HEAD@{2},或者类似的位置。用户需要根据实际情况选择正确的提交。 最后,需要验证每一步是否正确,以及是否存在其他情况需要考虑,比如是否有未提交的修改在操作过程中会被覆盖,或者是否需要撤销push再处理本地提交等。</think>要依次回退由 `git add .`、`git commit --amend` 和 `git push` 带来的更改,需按操作逆序逐步撤销。以下是具体步骤: --- ### 1. **撤销 `git push` 的强制推送** 若已通过 `git push -f` 将 `amend` 后的提交推送到远程仓库,需远程仓库回退到 `amend` 前的状态: ```bash # 查看提交历史,找到 amend 之前的提交哈希(如 abc123) git reflog # 强制将本地分支回退到 amend 前的提交 git reset --hard abc123 # 强制推送以覆盖远程分支(谨慎操作!) git push -f origin <分支名> ``` > **注意**:强制推送会影响团队协作,需提前通知其他成员[^5]。 --- ### 2. **撤销 `git commit --amend`** `amend` 会生成新提交替换原提交,需通过以下步骤回退: ```bash # 查看操作日志,找到 amend 前的提交哈希(如 def456) git reflog # 回退到 amend 前的提交(保留工作区修改) git reset --soft def456 ``` - 若需完全丢弃 `amend` 提交的修改(包括工作区文件),使用 `git reset --hard def456`[^5]。 --- ### 3. **撤销 `git add .`** 若需取消暂存区的文件(即撤销 `git add .` 的效果): ```bash # 取消所有文件的暂存状态 git restore --staged . # 或使用等效命令 git reset HEAD . ``` --- ### 完整操作示例 假设操作顺序为:`git add .` → `git commit --amend` → `git push -f`,回退流程如下: 1. **回退 `git push`**: ```bash git reflog git reset --hard abc123 git push -f origin main ``` 2. **回退 `git commit --amend`**: ```bash git reset --soft def456 ``` 3. **回退 `git add .`**: ```bash git restore --staged . ``` --- ### 关键注意事项 1. **强制推送的风险**:覆盖远程历史可能影响他人协作,需谨慎使用 `git push -f`。 2. **备份修改**:若工作区有未保存的修改,建议提交或暂存(`git stash`)。 3. **恢复误删提交**:通过 `git reflog` 可找回丢失的提交哈希[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值