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后的版本记录推送到远端

posted @ 2025-03-07 09:39  MKYC  阅读(50)  评论(0)    收藏  举报