git实战
目录
本文包含的场景来自于实战,包含以下内容:
- 场景1:误删除一个文件,如何恢复
- 场景2:修改了一个文件,想撤销修改
- 场景3:远端仓库其他用户新上库,本地未pull,先push,出现reject提醒
- 场景4:本地分支和远程分支关联
- 场景5:git批量操作
- 场景6:撤销某一次提交
- 场景7:git pull时提示merge是怎么回事
场景1:误删除一个文件,如何恢复
类型1:仅本地删除,未使用git add命令将删除操作添加到暂存区
可以使用 git checkout (Git 2.23 及以上版本)或者git restore命令来恢复文件。
# 使用git restore恢复文件
git restore your_deleted_file.txt
# 或者使用git checkout恢复文件(适用于旧版本Git)
git checkout -- your_deleted_file.txt
类型2:本地删除+git add到了暂存区,未使用git commit提交
操作步骤
- 第一步,查看工作区状态
使用git status命令查看当前工作区的状态,确认文件已被删除且已添加到暂存区。
输出可能会显示类似如下信息:
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: your_deleted_file.txt
- 第二步,将文件从暂存区移除
使用 git restore --staged 命令(Git 2.23 及以上版本)或 git reset HEAD 命令将文件从暂存区移除。
(1)使用 git restore --staged 命令
git restore --staged your_deleted_file.txt
(2)使用 git reset HEAD 命令(适用于旧版本 Git)
git reset HEAD your_deleted_file.txt - 第三步,恢复文件
此时文件已回到未添加到暂存区的状态,使用 git restore 或 git checkout 命令恢复文件,方法同情况一。
类型3:本地删除+git add+git commit均已完成,未push到远端
使用 git checkout 命令恢复,此方法是从之前的提交中检出文件版本到当前工作目录。
- 第一步,查看提交历史
使用 git log 命令查看提交历史记录,找到文件被删除之前的那个提交的哈希值。
git log
示例输出如下:
commit 123456789abcdef (HEAD -> main)
Author: Your Name <your_email@example.com>
Date: Sat Mar 8 12:00:00 2025 +0800
Delete your_deleted_file.txt
commit 987654321abcdef
Author: Your Name <your_email@example.com>
Date: Sat Mar 8 11:00:00 2025 +0800
Add some files
这里 987654321abcdef 就是文件被删除之前的提交哈希值。
- 第二步,恢复文件
使用 git checkout 命令从指定提交中恢复文件。
git checkout 987654321abcdef -- your_deleted_file.txt
执行上述命令后,文件 your_deleted_file.txt 就会被恢复到工作目录,但此时文件处于未暂存状态。
- 第三步,提交恢复操作
如果你希望保留这个恢复的文件状态,可以将其添加到暂存区并提交。
git add your_deleted_file.txt
git commit -m "Restore deleted file"
场景2:修改了一个文件,想撤销修改
方法和“场景2:误删除了一个文件”处理方法完全一致,也是分情况讨论。
场景3:远端仓库其他用户新上库,本地未pull,先push,出现reject提醒
方法一:先pull合并远程分支到本地分支
这种方法会尝试将远程仓库的更新合并到你当前的本地分支中。
# 拉取远程仓库的更新并尝试合并
git pull origin <远程分支名>
# 如果有冲突,需要手动解决冲突
# 解决冲突后,添加修改并提交
git add .
git commit -m "Merge remote changes"
# 再次尝试推送
git push origin <远程分支名>
在上述代码中,<远程分支名>通常是master或者main,你需要根据实际情况进行替换。git pull命令实际上是git fetch和git merge的组合。如果在合并过程中出现冲突,你需要手动编辑冲突文件,然后使用git add和git commit来标记冲突已解决。
方法二:使用git pull --rebase
git pull --rebase会将你本地的提交暂时保存,然后将远程仓库的更新应用到本地分支,最后再将你本地的提交应用到更新后的分支上。这种方法会使提交历史更加线性。
# 拉取远程仓库的更新并使用变基操作
git pull --rebase origin <远程分支名>
# 如果有冲突,需要手动解决冲突
# 解决冲突后,继续变基操作
git add .
git rebase --continue
# 再次尝试推送
git push origin <远程分支名>
如果在变基过程中出现冲突,你需要手动解决冲突,然后使用git rebase --continue继续变基操作。
场景4:本地分支和远程分支关联
为什么要关联
如果你希望在使用 git pull 和 git push 时无需每次都指定远程分支名,可以设置本地分支与远程分支的关联关系
如何关联
关联通常有三种办法:
(1)在push时关联;
本地分支和远程分支不同名:若要将本地的local-feature分支推送到远程仓库 origin 的remote-feature分支并建立关联,使用命令:
git push -u origin local-feature:remote-feature
本地分支和远程分支同名:假设你在本地有一个名为feature-branch的分支,要将其推送到远程仓库 origin 的同名分支并建立关联,可使用以下命令:
git push -u origin feature-branch
(2)在pull时关联;
假设远程仓库 origin 有一个 new-feature 分支,你要将其拉取到本地并创建一个同名的本地分支 new-feature ,同时建立关联,可使用以下命令:
git pull -u origin new-feature:new-feature
如果本地没有该分支,Git 会自动创建。
(3)其他情况下的关联;
git branch --set-upstream-to=origin/remote_new_branch local_new_branch
查看本地分支和远程分支的关联关系
git branch -vv
-vv选项是--verbose --verbose的缩写,它会显示本地分支对应的远程分支以及二者之间的提交差异信息。
输出示例
* main 1234567 [origin/main: ahead 1, behind 2] Some commit message
feature 89abcde [origin/feature-branch] Another commit message
结果解释
- 星号 * 表示当前所在的本地分支。
- 第一列是本地分支的名称,如 main 和 feature。
- 第二列是本地分支最新提交的哈希值的前几位,如 1234567 和 89abcde。
- 中括号 [] 内显示的是本地分支关联的远程分支信息:
- origin/main 表示 main 本地分支关联的远程分支是 origin 仓库下的 main 分支。
- ahead 1, behind 2 表示本地 main 分支比远程 origin/main 分支多 1 个提交,同时比远程分支少 2 个提交。
- origin/feature-branch 表示 feature 本地分支关联的远程分支是 origin 仓库下的 feature-branch 分支。
解除本地分支与远程分支的关联
git branch --unset-upstream <本地分支名>
当你所处的分支就是想解除的分支时,无需带上<本地分支名>;当不在该分支时,需带上<本地分支名>
场景5:git批量操作
当需要同时添加多个文件到 Git 暂存区时,挨个使用 git add <文件名> 命令确实效率较低。Git 提供了多种方法来批量添加文件,以下为你详细介绍:
使用通配符
通配符可以匹配多个文件,能让你一次性添加符合特定模式的文件。
添加所有同类型文件:如果你想添加所有扩展名为 .txt 的文件,可以使用如下命令:
git add *.txt
此命令会将当前目录下所有 .txt 文件添加到暂存区。
递归添加子目录文件:若要递归添加当前目录及其所有子目录下的 .py 文件,可以这样操作:
git add **/*.py
这里的 **/ 表示递归匹配任意数量的目录。
添加当前目录下所有文件
如果你想将当前目录下的所有文件和子目录(包括新文件、修改的文件和删除的文件)都添加到暂存区,可以使用:
git add .
如果你在项目根目录下执行此命令,它会递归地添加整个项目中的所有更改。需要注意的是,这会包含 .gitignore 文件中未忽略的所有文件。
添加所有已跟踪文件的更改
如果你只想添加那些已经被 Git 跟踪过且有更改的文件,可以使用:
git add -u
或者
git add --update
此命令会更新所有已跟踪文件的状态,将它们的更改添加到暂存区,但不会添加新文件。
添加所有更改(包括新文件和已跟踪文件)
若要一次性添加所有更改,包括新文件、修改的文件和删除的文件,可以使用:
git add -A
或者
git add --all
这个命令会递归地扫描整个工作目录,将所有更改添加到暂存区。
根据文件列表添加
如果你有一个包含多个文件名的列表文件(例如 files.txt,每行一个文件名),可以使用以下命令添加这些文件:
git add $(cat files.txt)
此命令会读取 files.txt 文件中的文件名,并将它们添加到暂存区。
场景6:撤销某一次提交
撤销最近一次 commit,但保留修改内容
若你只想撤销最近一次 commit,同时保留工作区和暂存区的修改内容,可使用:
git reset --soft HEAD~1。
- 这里的
--soft意味着只移动 HEAD 和分支引用,暂存区和工作区的内容不会改变。 HEAD代表当前所在的提交。HEAD~1代表当前提交的上一个提交。
--soft选项保证了暂存区和工作区的内容不变,这样你就可以重新组织提交。
撤销最近一次 commit,并重置暂存区,但保留工作区内容
如果你想撤销最近一次 commit,同时重置暂存区,不过保留工作区的修改内容,可使用:
git reset --mixed HEAD~1
--mixed是git reset的默认选项。--mixed选项会移动 HEAD 和分支引用,并且更新暂存区,使其和指定提交一致,但工作区内容不变。
撤销最近一次 commit,并丢弃工作区和暂存区的修改内容
若你要彻底撤销最近一次 commit,同时丢弃工作区和暂存区的修改内容,可使用:
git reset --hard HEAD~1
--hard选项会移动 HEAD 和分支引用,同时让暂存区和工作区都和指定提交一致,这会使工作区中未提交的修改丢失。
撤销指定的某次 commit
若你想撤销指定的某次 commit,而不是最近一次,可使用 git reset 加上具体的提交哈希值。
git reset --hard <commit-hash>
<commit-hash>是你想要回退到的提交的哈希值。你可以通过 git log 命令查看提交历史并获取该哈希值。
使用 git revert 撤销 commit
git revert 和 git reset 不同,它会创建一个新的 commit 来撤销指定的 commit,而不是直接删除提交历史。这在多人协作开发中非常有用,因为它不会改变已经存在的提交历史。
##第一步
git revert <commit-hash>`
##第二步
git push origin <branch-name>
<commit-hash>是你想要撤销的提交的哈希值。执行该命令后,Git 会创建一个新的 commit,其内容与指定的 commit 相反,从而达到撤销的目的。
场景7:git pull时提示merge是怎么回事
通常是因为本地有提交,远端仓也有提交,导致本地分支和远程分支的历史记录产生了分叉。该过程中的哈希值是怎样变化的?在此一探究竟。
如下图为本地未进行任何修改和提交时的哈希值,与远程库保持一致:

接下来本地对代码进行了修改,并提交到本地仓,此时看到本地仓多了一个哈希值5dbe:

然后在远端仓也进行了一次提交,远端仓多了一个新的哈希值6e0c:

然后本地直接使用git pull指令,和预想的一样,弹出了merge窗口,直接点击关闭。
此时再查看本地的哈希值如下:

使用git status查看状态:

该提示表明需使用push指令将merge后的版本记录推送到远端

浙公网安备 33010602011771号