Version-Control - Git

  1. 基本疏通 Walkthrough
    1. 安装Git
    2. Using HTTPS
    3. Using SourceTree + SSH
    4. Using SSH
  2. Merge
    1. Pull Request
  3. Rebase
  4. 回滚 Rollback
    1. Reset
    2. 回滚文件 Rollback Files
  5. 配置 config
  6. Commit message
  7. 其他 Others
  8. 扩展阅读 See Also
  9. 参考 References

基本疏通 Walkthrough

安装Git

在这个官网可以下载到最新版本得Git。在下载并点击安装后,下面是值得关注的点:

image-20210905181306041

使用 notepad++ 当编辑器

image-20210905181329148

一个新 repository 默认分支叫什么名称。Github 用的是 main,git 默认的是 master。相关讨论参考此处

image-20210905181548737

回车符的设置如图所示有三种

  1. 拉文件下来时候 LF=>CRLF,commit上去时,会 CRLF=>LF。window 环境使用。
  2. commit上去时,会 CRLF=>LF(如果是CRLF的时候)。unix 环境时候。
  3. 连 commit时候也不做任何的转换

image-20210905181838058

git pull 发生冲突时,选择的策略:

  1. merge
  2. rebase
  3. 什么都不做

这里选择 rebase ,只进行一次 merge。多次 merge 意义不大。image-20210906011444172

credential helper(存储凭证的工具)

image-20210906011820957

Using HTTPS

  1. 下载仓库 Clone from a remote Repository

    1
    2
    3
    4
    5
    6
    7
    8
    
    $ git clone https://github.com/caliburn1994/git_practice.git
    Cloning into 'git_practice'...
    remote: Enumerating objects: 17, done.
    remote: Counting objects: 100% (17/17), done.
    remote: Compressing objects: 100% (11/11), done.
    remote: Total 17 (delta 4), reused 0 (delta 0), pack-reused 0
    Receiving objects: 100% (17/17), done.
    $ cd git_practice/ # 本次示例使用的仓库
    
  2. 创建分支并切换,并推送

    1
    2
    
    $ git checkout -b iss53
    Switched to a new branch 'iss53'
    
  3. 当输入 git push 命令时,Github将会弹框并要求输入Access Token

    image-20210905175033182

    在 GitHub 的 setting 里生成 access token(如图所示的位置) ,并输入 token 到输入框。

    image-20210905175415950

    登陆后

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    $ git push --set-upstream origin iss53
    Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
    remote:
    remote: Create a pull request for 'iss53' on GitHub by visiting:
    remote:      https://github.com/caliburn1994/git_practice/pull/new/iss53
    remote:
    To https://github.com/caliburn1994/git_practice.git
     * [new branch]      iss53 -> iss53
    Branch 'iss53' set up to track remote branch 'iss53' from 'origin'.
    
  4. 提交文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    $ echo "# Java-Demo" >> README.md
    $ git add README.md
    $ git commit -m "first commit"
    [iss53 aaefaf0] first commit
     1 file changed, 1 insertion(+), 1 deletion(-)
    $ git push
    Enumerating objects: 5, done.
    Counting objects: 100% (5/5), done.
    Delta compression using up to 8 threads
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 285 bytes | 285.00 KiB/s, done.
    Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
    remote: Resolving deltas: 100% (1/1), completed with 1 local object.
    To https://github.com/caliburn1994/git_practice.git
       f35536a..aaefaf0  iss53 -> iss53
    

PS:

  • 输入的 token 将存在 Credential Manager 中。1

Using SourceTree + SSH

  1. 通过 PuTTY 生成 public key 和 private key

    image-20210905173316191

    保存 OpenSSH 格式的 private key 至 ~/.ssh/github.ppk

    image-20210911160748728

    复制 OpenSSH 格式的 public key

    img

  2. Github 的 SSH and GPG keys 里新创建一个 SSH key,并黏贴刚刚的 public key

    image-20210905173401959

  3. SSH-agent 添加 private key

    image-20210905173432746

    登录后

    image-20210905173445773

  4. 测试(clone a repository )

    image-20210905173551645

Using SSH

当我们通过 clone 下载项目,将会被拒绝,原因是没有 public key。

1
2
3
4
5
6
7
$ git clone git@github.com:caliburn1994/git_practice.git
Cloning into 'git_practice'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

再使用 putty 生成 key pair 之后,

1
2
$ ls ~/.ssh
github  github.openssh  github.ppk  known_hosts

然后继续在 GitHub 添加 SSH key (参考使用 Using SourceTree + SSH)

1
2
3
4
5
6
7
8
cat << EOF > ~/.ssh/config
Host github.com
    User git
    Hostname github.com
    IdentityFile ~/.ssh/github.ppk
    Port 22
    IdentitiesOnly yes
EOF

测试

1
2
3
4
5
6
7
8
9
10
$ ssh -T github.com
Hi caliburn1994! You've successfully authenticated, but GitHub does not provide shell access.
$ git clone git@github.com:caliburn1994/git_practice.git
Cloning into 'git_practice'...
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 28 (delta 5), reused 12 (delta 1), pack-reused 0
Receiving objects: 100% (28/28), 4.57 KiB | 212.00 KiB/s, done.
Resolving deltas: 100% (5/5), done.

Merge

merge 用于合并。merge 的方式有各种各样,但在 feature 分支合并到 master/main 主分支时,merge 请求往往需要管理员同意,此时的 merge 是单纯的按钮,而不是具体的命令,因此该 action 需要选择。

常见的 options 有:2

  1. merge
  2. rebase && merge --ff-only 线性 (linear)
  3. rebase && merge --no-ff 半线性的 (semi-linear)

img

ff 全称 fast forward,当禁止 fast forward 后,将会产生一个合并记录。默认似乎是 fast forward 模式。3 在提交 pull request 之后,可以看见该 options。

image-20210913012016407

相关讨论:

Pull Request

pull request 指的告知他人你已经修改了一些东西,等他人讨论和 review 完后,就可以 merge 到 base 分支。简而言之,就是 merge remote 分支。GitHub 现在提供了两种方式。4

image-20210913011651031

Rebase

使用 git rebase 可会修改本地 commit 的 base 位置。图源5

img

由于 Rebase 是<div class='sup' data-title="在操作后往往需要使用 git push --force">破坏性操作</div>,所以不应使用在 master/main 分支。

当想要在 master/main 分支达到 rebase feature 分支的效果,可以选择

  • 先 squash commits,然后 merge/rebase
  • 先 squash commits,然后 cherry-pick

以保证历史清晰,以及不显得突兀。

相关讨论:

回滚 Rollback

Reset

使用 reset 可以回滚分支到某个状态。reset 有三种选 options:6

  • soft (常用)
  • mixed
  • hard (常用)

enter image description here

回滚文件 Rollback Files

根据 How can I reset or revert a file to a specific revision? 一贴,大致有以下方法:

  1. reset
  2. revert
  3. checkout

由于 Jetbrain 提供的回滚功能十分方便,因此不对该话题进行讨论。而将历史文件导出的这种特殊需求,则可使用 checkout。

image-20210907084631441

配置 config

1
2
3
git config --list # 列出当前配置
git config --global user.name “[firstname lastname]”
git config --global user.email “[valid-email]”

Commit message

标签🏷

1
2
3
4
5
6
7
feat: 功能
fix: 修复bug
docs: 文档、readme.md
style: 代码格式,如: tab、空格、火车等
refactor: 重构
test: 一切与测试相关得
chore: 杂务。如:更新CICD代码,部署代码等等

相关的现成插件

TODO

  • 需要寻找现成规范 https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716

其他 Others

  • 使用 git commit --amend 可以覆盖上一个请求

  • git stash 和 IntelliJ IDEA 的 Shelve Changes 都可以将 changes 收起来,要用时候再恢复。(个人推荐 IDEA 的)7

    The stolen pictures were stashed (away) in a warehouse. 失竊的畫被藏匿在一個倉庫裡。

    I've had to shelve my plans to buy a new car, because I can't afford it at the moment. 我不得不延緩買新車的計劃,因爲目前我還買不起。

  • git squash 可以压缩 commits。

    The room was so full you couldn't squash another person in. 房間裡擠得滿滿的,再也不進一個人了。

  • git cherry-pick 将其他分支的 commit 复制到当前分支上。

  • git push --force 覆盖当前分支

  • git pull = git fetch + git mergegit fetch 可以更新本地的远程分支历史。

扩展阅读 See Also

参考 References