乐趣区

关于前端:一些常用的-Git-进阶知识与技巧

1. 同一电脑存在多个 Git 账号

假如咱们在同一电脑上领有多个 Git 账号,例如公司外部应用的是 Gitlab,集体应用的是 Github 或者 Gitee。那就会遇到一种状况,下班时想给集体开源我的项目提交代码,然而 Git 绑定的是公司的账号。

在这种状况下,咱们能够让 Git 绑定多个不同的 ssh key,每个 ssh key 对应一个不同的 Git 服务器。

生成第一个 ssh key:

ssh-keygen -t rsa -C "xxx@xxx.xx"

生成第二个 ssh key:

ssh-keygen -t rsa -f path/to/file  -C "xxx@xxx.xx"

参数 -f 示意指定生成的文件名,path/to/file 是文件名门路,例如 ~/.ssh/id_rsa_github

执行下面两条命令后会失去两对 ssh key。

这时还须要在该目录下创立一个 config 文件。写上以下内容:

Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_github # 私钥文件门路
                                                            
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_rsa

Host gitee.com
HostName gitee.com
User git
IdentityFile ~/.ssh/id_rsa_github

这个配置文件的作用是指定私钥文件地位。

而后咱们能够把第一个密钥配置到公司的 Gitlab 服务器,并把相应的 Git 账号和邮箱设成全局。

git config --global user.name "xxx"
git config --global user.email "xxx@xxx.xx"

而后把另一对 ssh key 配置到 Github 上,并在电脑上的 Github 我的项目里独自配置 Git 用户姓名和邮箱。

git config user.name "xxx"
git config user.email "xxx@xxx.xx"

至此,咱们就功败垂成了。能够同时在不同的 Gitlab 和 Github 我的项目上提交代码了。

2. 批改 git commit 记录的用户姓名和邮箱

假如电脑上同时存在 Gitlab 和 Github 我的项目,其中 Gitlab 用户信息曾经全局配置过了。当初新拉了一个 Github 我的项目,提交了一个 commit 并且曾经推送到了近程仓库。这时发现该我的项目未配置 Github 的用户信息,默认应用的是全局账号 Gitlab 的用户信息。

咱们能够通过以下命令来批改最近一次提交的用户信息:

git commit --amend --author="username <yyy@ccc.com>" --no-edit

username 是用户名,用户邮箱旁边的 <> 符号不能去掉。批改后再执行 git push -f 推送到近程仓库。

如果要批改多个 commit 的用户信息怎么办?能够通过以下的代码来批改:

git filter-branch --commit-filter 'if ["$GIT_AUTHOR_EMAIL"="tanguangzhi@shiqiao.com"];
    then
            GIT_AUTHOR_NAME="woai3c";
            GIT_AUTHOR_EMAIL="411020382@qq.com";
            git commit-tree "$@";
    else
            git commit-tree "$@";
    fi' HEAD

将上述代码中的用户名和邮箱批改后,保留为 .sh 格局的文件,例如 edit.sh。而后在我的项目根目录下执行 sh edit.sh(windows 下可右击 -> Git Bash Here -> sh edit.sh),再执行 git push -f 强推即可。

3. 批改某个历史记录的音讯

假如以后分支有 a b c d 四个 commit 记录:

a
b
c
d

如果你想对 c 记录的音讯进行批改。能够应用 git rebasec 记录换到最后面,而后应用 git commit --amend 对其音讯进行批改。

具体操作步骤

执行以下命令对记录 d 后面的三个 commit 进行编辑:

git rebase -i d

进行 vim 编辑界面后,挪动光标到 c 记录上,按下 dd 剪切该记录,而后挪动光标到第一行,按下 p 粘贴,再输出 :wq 保留。

执行 git commit --amend 对切换程序后的 c 记录进行批改。进入 vim 编辑界面后,按 i 进行批改,而后按 ESC,再输出 :wq 保留。

最初用后面讲过的 git rebase 操作将 c 记录复原到原来的地位。

这个过程的执行后果就和上图一样,这是以后分支批改后和近程分支上的比照,箭头指向的记录音讯就是批改后的音讯。

如果想把批改后的记录同步到近程仓库,这时只有执行 git push -f 就能够了。

第二种形式

  1. 应用 git checkout -b <branchName> c 从指定记录切出一个分支
  2. 在新分支应用 git commit --amend 批改提交音讯
  3. 应用 git cherry-pickb a 记录,追加到新分支( 留神 ,这里的 b a 提交记录是指原分支上的 commit,也就是选取原分支上的 b a 记录增加到新分支上,这样新分支上的记录就变成了 a b c,并且 c 记录的提交音讯在第二步曾经批改过)
  4. 应用 git checout 原分支名 切换回原来的分支,再执行 git rebase <branchName> 合并新分支,最初强推到近程分支

4. 筛选指定的 commit 进行合并

假如你切了一个 bugFix 分支来修复线上 bug,通过一段时间的致力后终于将 bug 修复了。然而为了调试(加了很多 debug 代码)或其余起因,bugFix 上多了很多无用的记录音讯。

commit3: 修复登录 bug
commit2: 增加 debug 语句
commit1: 增加 console 语句 

例如下面的三个记录,后面的两个记录增加了很多调试代码,在最初一个记录终于修复了 bug,并且删除了调试代码。这时如果间接将 bugFix 分支合到 master 分支,就会把调试的记录也合并进来。

这时能够应用 git cherry-pick 只将最初一个记录合并到 master 分支。或者应用 git rebase 将 bugFix 分支另外两个记录摈弃,而后再合并。

5. ^~ 的区别

操作符 ^~ 符一样,前面也能够跟一个数字。~ 示意向上返回几代记录。

然而该操作符前面的数字与 ~ 前面的不同,并不是用来指定向上返回几代,而是指定合并提交记录的第几个父记录。

Git 默认抉择合并提交的“第一个”父记录,在操作符 ^ 后跟一个数字能够扭转这一默认行为。

单看文字可能不太好了解,上面看几个示例。

执行命令 git checkout main^ 回到第一个父记录(原来 HEAD 指向 c3,当初指向 c1)。

执行命令 git checkout main^2 回到第二个父记录(原来 HEAD 指向 c3,当初指向 c2)。

最初再来一个更简单的示例:

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     |/    |
      B     C
       \   /
        \ /
         A
A =      = A^0
B = A^   = A^1     = A~1
C = A^2  = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2

通过这些示例咱们还能发现 ~n 等于间断的 n 个 ^

6. git revertgit reset 的区别

git reset 能够回退 Git 的历史记录。例如以后分支有三个记录,并且 HEAD 指向 c 记录:

c <- HEAD
b 
a

如果咱们想回退到 b 记录,只有执行 git reset b 就能够了:

b <- HEAD 
a

接着应用 git push -f 将回退版本后的分支强制推送到近程仓库,这样本地分支和近程分支就同步了。

git push -f

git revert 也能够撤销记录,只不过它撤销的记录不会隐没,这一点和 git reset 不一样。git reset 撤销的记录就跟隐没了一样。

当初咱们用 git revert 来从新演示下方才的操作:

c
b 
a

如果咱们执行 git revert b,则会在以后分支上再生成一个新的 commit 记录,变成 a b c b',这个 b' 的状态和记录 b 是一样的。

也就是说,执行 git reset b 后,以后的分支记录会变成 a b。执行 git revert b 后,以后的分支记录会变成 a b c b'

如果你想让他人晓得你撤销过记录,就应用 git revert,因为它会留下撤销的记录,否则用 git reset

参考资料

  • 一台电脑绑定两个 git 帐号 (GitHub 和 GitLab)
  • Git- 工具 - 重写历史
  • learngitbranching
退出移动版