What & How & Why

这是本文档旧的修订版!


Git & GitHub

Git / GitHub Notes


Git

基础流程与相关命令

Git 分为三个区域:工作区暂存区版本库

  • 工作区(Working area):进行工作的区域,比如建立,编辑,分类文件等
  • 暂存区(Staging area):存放修改过的文件
  • 版本库(Repository):存储当前软件的某个正式版本
工作流程

Git 的基本工作流程是,在工作区创建好文件,然后将文件提交到暂存区;确认无误后将改动提交到版本库,作为新的版本发布:

<html>

<img src=“/_media/software_dev/ver_ctrl/git_basic_workflow.svg” width=“600”>

</html>

相关命令
  • git init:将当前的文件夹转化为 git 项目文件夹
  • git status:查看当前文件夹的中文件的状态
  • git add:将工作区的文件添加到暂存区
  • git diff:查看指定文件在工作区与暂存区之间的不同
  • git commit:将暂存区的文件提交至版本库
  • git git log:查看 commit 的历史
git diff

打印信息的例子:

#git diff output example

#white, nothing changed, indicated in white
  * @Author: Codinghare
  * @Date:   2022-05-22 21:42:56
  * @Last Modified by:   hare

#start with "-", removed or replaced, indicated in red
- * @Last Modified time: 2022-05-30 00:16:57

#start with "+", changes to the file, indicated in green.
+ * @Last Modified time: 2022-05-30 00:42:45
退出使用按键 q 即可。

git commit

git commit 有一个非常好用的 tag amend。这个 tag 允许我们对当前最新的 commit 进行更新,而不是创建一个新的 commit。这个命令在修改当前 commit 中的一些细小错误时非常有用。

当然,虽然看上去是”更新“了 commit,amand 实际上还是创建了一个新的 commit,并取代了旧的 commit(只是不会有新的 commit)记录。但终端会弹出界面要求我们重新书写 comment(-m 里写的东西)。如果要维持之前的 comment,使用下面的命令:

git commit --amend --no-edit

git log

打印信息的例子:

#SHA, unique id for the commit
commit 5f9c857051c2a9acc2036e90b4c965e16798bd6b
#Author
Author: hare <[email protected]>
#Date
Date:   Thu Jun 2 23:14:49 2022 -0600
#comments, generated by git commit -m " "
fixed typos.
一些相关的 tag:
git log --online 		  #shows the list of commits in one line format.
git log -S "keyword" 	  #displays a list of commits that contain the keyword in the message.
git log --oneline --graph #Displays a visual representation of how the branches and commits

Backtracking

BackTracking 的主要内容:

  • 将不符合要求的文件移除暂存区
  • 将工作区中被错误修改的文件回滚到未修改之前的状态
  • 将当前的 commit 回滚到之前某次的 commit

关键的概念:

  • 当前最新的 commit 被成为 HEAD commit.
  • reset 命令会更改当前的 HEAD commit 到指定的 commit
相关命令
  • git show HEAD:查看当前最新的 commit 的信息。信息额外包括了文件的变动信息。
  • git checkout HEAD取消 HEAD commit 做出的改动。
  • git checkout - -:上面命令的简化版本。
  • git reset HEAD:将 staging 区域中的文件移除
  • git reset commit_SHA:将 staging 区域中的文件重置为与 指定 SHA commit 中一致。commit_SHA 是 commit SHA 的头 7
  • git stash:将当前未完成的工作赞存入一个临时区域(临时区域可拥有多个)
  • git stash pop:取回临时区域的内容
git reset / checkout
  • git reset 通常用于暂存区中存在着不符合要求文件的情况。比如不小心将错误的源文件送至暂存区后,可以使用 reset 命令将其移除出暂存区。需要注意的是,如果指定了 commit 的 SHA,则该 commit 会成为当前的 HEAD commit。需要注意的是,reset 命令是无法取消处于工作区文件的修改的。
  • git checkout 则是对工作区的文件进行还原。当不小心修改了工作区中的文件时,可以利用该命令将其还原到 HEAD commit 时文件的状态,也就是没有被修改前的状态。
git stash

这个命令主要用于保存当前未完成的工作。比如当我们正在进行工作 A(brach A),然后接到要求去 B(branch B)进行另外工作的要求。此时我们就可以使用 git stash 将 A 这边的工作暂存;当完成 B 的工作后,回到 A,使用 git stash pop 就可以将之前未完成的工作取回,接着进行工作了。

这个命令避免了将未完成的文件进行 commit 的情形。该临时暂存的档案可以建立多个,可以通过 git stash –list 查看。

temp

  • git alias:使用该命令可以对 git 当前命令进行 alias,允许我们使用更短的命令代替原有的命令:

$ git config --global alias.co "checkout"
$ git config --global alias.br "branch"
$ git config --global alias.glop "log --pretty=format:"%h %s" --graph"

Branching

Git 允许创建不同的 branch 来对项目进行实验;也就是说,新的 branch 是作为之前版本的改动而存在的;我们可以在新的 branch 中进行开发和实验,直到功能稳定之后再合并到主要版本中,再作为新的项目版本进行发布。新的 branch 包括两部分:

  • 之前 master branch 的内容(所有 commit)
  • 新 branch 自身拥有的内容
相关命令
  • git branch:查看当前所在的 branch。
  • git branch new_branch:建立名为 new_branch 的新 branch。
  • git checkout branch_name:切换到名为 branch_name 的 branch
  • git merge branch_name:合并名为 branch_name 的 branch 到 master
temp

$ git merge fencing
Updating 79a1cc5..3eba879
Fast-forward
 resume.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

merge conflict

合并 branch 到 master 的前提是,master 在 branch 新建之后没有发生改变。如果改变发生,之后再将 branch 合并回 master,会造成合并冲突(merge conflict)。这种冲突是因为 master 的不一致导致的。

当冲突发生的时候,会产生如下的信息:

Auto-merging conflict_file_name
CONFLICT (content): Merge conflict in conflict_file_name
Automatic merge failed; fix conflicts and then commit the result.
之后我们再打开冲突发生的文件,会有如下的内容:
#master version
<<<<<<< HEAD
-content of master version 
=======
#branch version
-content of branch version
>>>>>>> branch
-------------------

Git Hub

GitHub 的简单工作流程

  1. 建立 新的 branch
  2. commit
  3. 建立 pull request
  4. 等待 reviewer 的审查通过
  5. 合并当前 branch 到 master branch,并删除当前 branch


<html>

<img src=“/_media/software_dev/ver_ctrl/github_flow.svg” width=“700”>

</html>

新建 branch 的必要性
  • 防止冲突
  • 保证主项目(master branch)不受开发进程的影响
branch 的命名方式

#author + branch type + short branch description 
hare_feature_dashboard_notifications

pull request 的注意事项
  • 提供足够的细节以便节省 review 的时间
  • PR 较小的更新,让 review 更快更容易
review 的注意事项
  • comment 应该包括需要修改的内容和原因
  • 清晰的表达自身的意思
  • 指出潜在的问题

添加 github 远程仓库

首先查找用户主目录下有没有 id_rsaid_rsa.pub 的文件,如果没有,使用以下命令生成 key(命令中的邮箱使用自己的邮箱):

ssh-keygen -t rsa -C "[email protected]"
运行以上命令后访问 .ssh 目录,会找到 id_rsaid_rsa.pub 两个文件,前者是私有密钥,需要妥善保存;后者是公有密钥,可以放心告诉别人。

接下来到 Github 中的 seting 中找到 SSH and GPG keys,将刚才生成的 id_rsa.pub 中的内容作为一个新的 SSH key 添加到 GitHub中。

添加完成之后可以输入如下命令测试是否连接成功:
ssh -T [email protected]
如果显示以下文本就证明连接成功了:
Hi XXXX! You've successfully authenticated, but GitHub does not provide shell access.
到此就可以使用 git 命令对远程库操作了。

Trouble shooting

使用 WSL 的问题
GitHub Error Message - Permission denied (publickey)

可能的解决方案:

  • 不使用 sudo 进行 Git 命令的使用
  • 如果出现以下错误:

Git XXX: fatal: could not set 'core.filemode' to 'false'
尝试修改 /etc/wsl.conf,添加以下代码(没有则创建):
[automount]
options = "metadata"
之后运行:
wsl --shutdown
重启即可