Skip to content

一文搞定 git 相关的工作流

1.git merge 和 git rebase?合并分支

git mergegit rebase 都是用于整合 Git 分支的命令,但它们的工作方式和效果不同。它们各自在处理分支合并的场景中有不同的优劣和用途。

  1. Git Merge:
    • git merge 用于将一个分支的更改合并到另一个分支中。合并操作会创建一个新的合并提交,将两个分支的更改合并在一起。这个合并提交将有多个父提交,表示两个分支的历史交汇点。
    • 合并保留了原始分支的提交历史,可以清晰地看到哪些更改来自哪个分支。
    • 在多人协作的项目中,合并是常见的操作,特别是在将功能分支或修复分支合并回主分支时。
    • 合并会保留分支的拓扑结构,但可能会导致提交历史变得较为复杂。
bash
# 合并分支"feature"到当前分支
git merge feature
  1. Git Rebase:
  • git rebase 用于将一个分支的更改移动到另一个分支的顶部。这个操作会将当前分支的提交逐个应用到目标分支上,并创建一个线性的提交历史。
  • Rebase 的效果是,似乎所有更改都是在目标分支上进行的,使历史记录更加清晰。但它也会修改提交历史,因此不应在公共分支上进行 rebase,以免影响其他人。
  • Rebase 可以使提交历史变得更加简洁和易于阅读,但也可能会引入冲突,需要解决。
  • 在个人分支或临时分支中,通过 rebase 来跟上目标分支的变化是一个常见的操作。
bash
# 将当前分支的更改重新应用到"main"分支的顶部
git rebase main

总结:

  • git merge 会创建一个新的合并提交,保留分支的拓扑结构,适合多人协作的场景。——> 会创建一个新的提交,里面展示详细的提交记录 ——> 合并其他分支到当前
  • git rebase 会将提交逐个应用到目标分支上,创建线性历史,适合个人分支或在本地进行操作的场景。——> **会修改目标分支的提交历史,合到一起 **——> 将当前分支合并到其他分支
  • 在公共分支上,通常应使用 git merge,而在个人分支上,可以考虑使用 git rebase 以保持历史整洁。

2.git reset 回退

git reset 这个就是进行回退的具体命令,这里先介绍他的几个参数

--soft 、--mixed 以及--hard 是三个恢复等级。

  • 使用--soft 就仅仅将头指针恢复,已经 add 的暂存区以及工作空间的所有东西都不变。

  • 如果使用--mixed,就将头恢复掉,已经 add 的暂存区也会丢失掉,工作空间的代码什么的是不变的。

  • 如果使用--hard,那么一切就全都恢复了,头变,aad 的暂存区消失,代码什么的也恢复到以前状态。

进行回退操作

下面我们开始进行具体的回退操作命令:

  • git reset --hard :进行已修改或者暂存,但未提交文件的回退

  • git reset --hard origin/master ”进行已提交,但未推送的版本回退

  • 1: git reset --hard HEAD^ 2:git push -f 这两条命令是进行已提交且推送的回退,git reset --hard HEAD^为先回退到上一个版本,git push -f 是进行强制推送,覆盖远程分支。 上面的--hard 可以替换成其它的恢复等级,一般用--soft,这样一些修改的内容不会丢失。

各种版本回退举例

js
git reset --hard head #当前版本
git reset --hard HEAD^ #回退到上一个版本
git reset --hard HEAD^^ #回退到上上一个版本
git reset --hard HEAD~3 #回退到往上3个版本
git reset --hard HEAD~10 #回退到往上10个版本

我们还可以用 git log 或者 git reflog 查看版本的记录,用版本号来恢复到指定的版本。如

git reset --hard 710ae83 其中 710ae83 是版本号;

回退后,可以再用 log 和 relog 查看下版本的记录,对比下他们的区别。

git 远程覆盖本地

当然,我们也可以直接用远程仓库的代码直接覆盖本地的仓库,这里我就不多哆嗦了,直接给大家奉上命令:

js
git fetch —all
git reset —hard orgin/master  #(master可以修改成其它要被覆盖的分支)
git pull

git fetch 只是下载远程库的内容,不做任务的合并

git reset 把 HEAD 指向刚刚下载的最新版本

注意:git revert 也是可以回退的,那么 revert 和 reset 有什么区别呢?

在 Git 中,可以使用不同的命令来回退或还原代码库中的提交。下面介绍几个常用的方法:

  1. git reset:使用 git reset 命令可以将代码库的 HEAD 指针移动到指定的提交,从而回退代码库的状态。常见的用法包括:
    • git reset <commit>将 HEAD 指针移动到指定的 <commit>,并将后续的提交从历史记录中移除。这样可以回退到指定提交之前的状态。注意,这个操作不会保留后续提交的更改。——> git reset 默认采用硬重置,对标 git rebase
    • git reset --hard <commit>:执行硬重置,将 HEAD 指针和工作目录都回退到指定的 <commit> 的状态。这将丢失未提交的更改,请谨慎使用。
    • git reset --soft <commit>:执行软重置,只将 HEAD 指针移动到指定的 <commit>,但保留所有更改。这允许你重新提交更改,或者创建一个新的分支来保存回退的提交。
  2. git revert:使用 git revert 命令可以创建一个新的提交,来撤销指定提交的更改。这种方式不会直接修改提交历史,而是创建一个新的提交来反转先前的更改。常见的用法包括:
    • git revert <commit>:撤销指定的 <commit>,并且创建一个新的提交来反转其更改。——> 对标 git merge

无论使用 git reset 还是 git revert,都要谨慎操作,特别是在与他人合作的项目中,避免对共享的代码库造成意外影响。另外,如果已经将更改推送到远程仓库,对于已经分享的提交历史进行修改是不推荐的,因为会破坏其他开发者的基于该历史提交的工作。

3.git checkout .

git checkout . 的作用

git checkout . 是一个 Git 命令,它用于撤销对工作目录中所有文件的修改,将其还原为与当前分支最新提交一致的状态。

执行 git checkout . 的效果如下:

  1. 所有已修改但未暂存的文件将会被还原到它们在最新提交时的状态,即恢复为最近一次提交后的文件内容。
  2. 所有已添加到暂存区但尚未提交的文件也会被移除,即取消暂存并还原为最近一次提交后的文件内容。
  3. 所有新创建的但尚未添加到暂存区的文件会被删除,即新创建的文件将不再存在。

需要注意的是,git checkout . 是一个危险的命令,它会无条件地将工作目录中的文件还原为最近一次提交的状态。因此,在执行该命令之前,请确保你已经保存了对文件的所有重要修改,因为它会永久性地丢弃尚未提交的更改。

如果你只想撤销某个文件的修改而不是整个工作目录,可以使用 git checkout <file> 命令,其中 <file> 是要还原的特定文件路径。这将只影响指定的文件,而不是整个工作目录。

具体的应用:

在我们才拉下来代码,忘记修改分支的时候,更改了代码,但是我们不想要这些更改

或者在我们 add 了一些代码,或者改错了一些代码

我们可以使用git checkout . 去还原仓库原本的状态,到上一次提交的时候,或者才 clone 下来的时候

然后再 git checkout 对应的分支名

4.创建新分支并推送代码的流程

bash
#查看当前所处分支
git branch
#新建git分支名为dev,并切换到新建分支dev上
git checkout -b dev #如果远程已经有了dev分支,那就直接git checkout dev即可,不用再新建
#查看是否切换到新建分支dev
git branch
#添加
git add .
#提交
git commit -m '提交文件时的说明'
#将文件推送到dev分支
git push origin dev

5.git 仓库推送配置名字和邮箱

bash
git config user.email "1558637209@qq.com"
git config user.name "郝文海"
bash
git config user.email "haowenhai@songshuai.com"
git config user.name "haowenhai"
bash
git config user.email "1558637209@qq.com"
git config user.name "forFishbonein"

6.本地项目与一个新仓库(某个特定分支)进行关联并推送的步骤

(一)最完整的流程

1.如果本地项目已经推送到过其他的仓库,那么就把文件复制到新的文件夹再进行推送!

一定不要用之前推送过到其他仓库的文件进行直接推送

要新建一个新的空白文件夹,把前面的项目所有文件拷贝过来,然后再进行推送

2.非常需要注意:一定要删除所有的.git 文件,将所有提交记录清除,否则之前提交过的文件本次就提交不了了,导致文件提交推送的不全!

mac 中要用 ls -a 才可以看到 .git 文件,执行以下命令删除 .git 文件夹:rm -rf .git

3.然后进行初始化 git init

4.然后切换本地的分支

git checkout -b 本地分支

5.如果本地和远程没有关联先用命令关联:(其实只要在 push 之前设置了即可)

移除与原仓库相关的远程仓库地址:

bash
git remote remove origin

查看关联的远程链接:git remote -v

image-20230621100820282

新增关联:

git remote add origin <新仓库的远程仓库地址>

git remote add origin http://gitlab.yx/general/react-manage-demo.git

注意:有时可能要用这个域名 git remote add origin http://gitlab.classba.com.cn/general/react-manage-demo.git

如果 vpn 不稳定的时候,这个域名可能更快

6.提交文件:

git add .

git commit -m “first commit”

这里一定要注意观察一下,提交的文件是否正确,是否有没有提交上去的文件

7.如果远程的空仓库只有一个 readme 文件(或者其他文件,如果有冲突的话推荐用 idea),那么提交之前一定要先拉取

直接拉取如果不行的话就用:

git pull origin 远程分支 --allow-unrelated-histories

git pull origin dev3 --allow-unrelated-histories

命令介绍:因为本地仓库没有接触过这个仓库,所以文件的历史没有任何相同的,必须用这个命令

git pull origin <远程分支> --allow-unrelated-histories 是一个 Git 命令,用于将远程仓库的更改合并到本地分支。--allow-unrelated-histories 参数是为了允许合并没有共同历史的两个分支。

当执行 git pull 命令时,Git 会尝试自动合并远程分支和本地分支的更改。然而,如果两个分支的提交历史没有共同的祖先,Git 默认会拒绝合并,因为它无法确定如何自动合并这些不相关的历史。这时需要使用 --allow-unrelated-histories 参数来告诉 Git 允许合并没有共同历史的分支。

注意:git pull origin 后面跟着的是远程分支名字

例如:远程仓库 originmain 分支 应该是 origin main

注意:origin 只是一个默认的远程仓库名称,对应于 origin 这个远程仓库名称,默认情况下,它会在本地创建一个名为 origin 的远程仓库引用。这个本地引用充当了与远程仓库通信的桥梁。

git remote show 命令来查看本地仓库的远程引用列表:

image-20230621102616030

8.有可能推送的时候需要用户名密码:

Username haowenhai

Password T5oRLaqylgQp

9.git push -u origin <本地分支名称>:<远程分支名称>

git push -u origin dev3:dev3

命令介绍:用于将本地分支的提交推送到远程仓库中的指定分支

  • git push: 将本地的提交推送到远程仓库。
  • -u origin: -u 参数用于将本地分支与指定的远程仓库(origin)关联起来,创建一个跟踪关系,以后可以直接使用 git push 来推送代码,无需再指定远程仓库和分支。
  • <本地分支名称>: 指定要推送的本地分支的名称。
  • :<远程分支名称>: 指定将本地分支推送到远程仓库的哪个分支,可以是已存在的分支,也可以是新的分支名称。

注意:如果本地分支名称和远程一样,那么可以不用写<本地分支名称>:<远程分支名称>,直接写<分支名称>即可

比如git push -u origin master 是将本地的 master 分支的提交推送到远程仓库(通常是名为 origin 的默认远程仓库)的 master 分支,并且建立跟踪关系

git push -u origin dev 是将本地的 dev 分支的提交推送到远程仓库(通常是名为 origin 的默认远程仓库)的 dev 分支,并且建立跟踪关系。

注意:-u 就是建立跟踪关系的意思

git push -u origin dev 命令中,-u--set-upstream 的简写形式。

--set-upstream 选项用于将本地分支与远程分支建立关联。当使用 -u--set-upstream 选项时,Git 会将本地分支推送到远程仓库,并且将远程分支设置为该本地分支的上游(upstream)分支。

(只有第一次推送需要写这个,后面直接 git push 即可,不用加-u origin <分支名称>了)

10.如果以上流程失败了,我们要重来,之前做如下事情:

  • git 文件包括了我们所有的提交记录,一旦出了提交的问题,我们应该先把这个文件删掉,再重新开始

  • 可以在远程再新建一个分支,这个分支应该是空的,然后再重新走流程(否则需要覆盖远程的分支内容,或者进行 merge,比较麻烦)

(二)git clone 的方法

还有一种方法是先 git clone 远程的空项目(可能有一两个文件),然后再把文件该删的删该补的补,弄成我们希望的样子,然后最后再统一提交上去,可能也可以!并且相对简单一些!

(三)远程仓库提交的文件不对,我们不想要了,又不想在远程删除

我们可以用如下方法,把本次提交的完整的正确的内容覆盖远程的所有内容

  1. 执行以下命令,将仓库的 HEAD 重置为初始状态:清空.git 文件的所有提交历史,让本地变成没有提交过的,并切换到一个新的分支

    bash
    git checkout --orphan <新分支名>
  2. 执行以下命令,将当前的更改添加到新的分支并进行提交:

    bash
    git commit -m "Initial commit"
  3. 执行以下命令,删除其他分支(除了当前分支):

    bash
    git branch -D <分支名>

    branch_name 替换为你想删除的分支名称,可以多次执行该命令以删除多个分支。

  4. 最后,执行以下命令来强制推送更改到远程仓库:(直接覆盖远程的)

    bash
    git push origin --force --all

    这将覆盖远程仓库的提交记录。

完成以上步骤后,你的仓库将不再包含之前的提交记录,相当于清空了所有的提交历史。请谨慎执行以上操作,确保你已经备份了重要的代码和数据。

7.所有常用命令的总结

bash
git clone
git add
git commit
git push
git pull
git branch
git checkout
git merge , git rebase
git reset
git config
git remote add origin http://gitlab.yx/general/react-manage-demo.git