Git笔记

学习建议

廖雪峰Git教程 比较详细,可操作性也比较强,在评论区可以找到勘误
Git官方推荐的《Pro Git》也很不错,推荐掌握了一定Git基础后再看
对于没有 Linux 基础,或者文字版学起来比较困难的朋友可以看系列视频教程 互联网人都该懂点 Git
Linux 下最常用的编辑器就是 Vim,然而第一用可能会让你怀疑人生,建议先学习一下 :使用Vim创建和编辑文本文件

注意点

Git 2.23 (2019.8.16)
git checkout 这个命令被拆分成了两个新命令:git switch 和 git restore
创建并切换到dev分支:git checkout -b dev 现在用git switch -c dev 效果相同

初始配置

安装Git Bash后需要做初始配置

  1. 用户名邮箱
# 任意文件夹右键 点击“ Git Bash Here ”
# ""内替换为自己的用户名和邮箱
git config --global user.name "username"
git config --global user.email "email"

# 查看配置是否成功
git config user.name
git config user.email
  1. SSH 免密登录
# ssh-keygen 用于生成,管理和转换身份验证密钥
# -t:密钥的类型 
# -C:用于识别这个密钥的注释(不添加注释直接ssh-keygen -t rsa也不影响使用)
ssh-keygen -t rsa -C "邮箱地址"

# 连续按3次回车

# 将用户目录下.ssh文件夹内的id_rsa.pub的内容粘贴到GitHub的SSH Keys中
# 具体位置:GitHub Settings -> SSH and GPG keys -> SSH keys

# 测试是否成功 Github 
# 码云测试命令为:ssh git@gitee.com 反馈的结果与 GitHub 类似

ssh git@github.com

# Are you sure you want to continue connecting (yes/no)? 
# 这时需要输入:yes

#成功会提示成功认证你的账户
# Hi aaronlinv! You've successfully authenticated, but GitHub does not provide shell access.
# Connection to github.com closed.

场景0:Git 基本使用

# 新建文件夹,初始化为Git仓库
mkdir learn-git
cd learn-git
git init

# 在当前目录添加并编辑文件(不熟悉 vim 编辑器可以用其他编辑器新建文件并编辑文件 )
vim test.txt

# 查看文件状态 test.txt现在为Untracked状态
git status

# 添加文件到暂存区
git add test.txt

# 提交commit -m 代表添加一个“提交信息”
git commit -m "add test.txt"

# 推送到 GitHub(在 GitHub 上创建空白仓库,并复制仓库地址)
# "git@github.com:aaronlinv/learn-git.git" 需要替换为自己新建的仓库地址
# 先添加远端仓库
# origin:远端仓库的别名(默认origin)
git remote add origin git@github.com:aaronlinv/learn-git.git

# 查看远端操作(会显示 fetch和push)
git remote -v 

# 推送到远端仓库(使用SSH协议需要配置SSH免密登录)
git push -u origin master
# -u:指定默认远端仓库别名,下一次推送只需使用git push
# origin:远端仓库的别名(默认origin)
# master:分支名称

push 是可能会遇到报错:refusing to merge unrelated histories
原因是远程仓库和本地仓库做了不同的改变并commit,导致本地仓库和远程仓库变成了独立的两个仓库,所以不能直接合并,执行以下命令合并代码,再push即可

git pull origin master --allow-unrelated-histories

场景1:克隆仓库

# 克隆仓库到本地(可以使用HTTPS或者SSH协议)
# "https://github.com/aaronlinv/learn-git.git" 为目标仓库地址
git clone https://github.com/aaronlinv/learn-git.git

# Git会新建一个与仓库名同名的文件夹,进入文件夹
# "learn-git" 为项目名称
cd learn-git

# 如果这个仓库已经克隆很久了,本地和远程可能存在差异了,可以拉取远程仓库最新状态到本地仓库
git pull

场景2:分支管理

# 已经克隆仓库到本地
# 开始工作前,先拉取远程最新修改(可能同事已经修改代码并提交了commit)
git pull

# 新建并跳转到dev分支(也可使用git branch -b dev)
git switch -c dev

# 查看分支情况
git branch

# 可以在dev 分支上修改代码做add和commit

# 推送dev分支到远程(需要拥有远端仓库的权限)
git push origin dev
# 如果需要重命名远端分支则加上 :f1
git push origin dev:f1

# 删除远端dev分支
git push origin :dev 

# 合并dev分支到master(需要先切换到master分支,在merge的过程可能需要解决冲突)
git switch master
git merge --no-ff dev 

# 查看分支合并情况
git log --graph --pretty=oneline --abbrev-commit

# 删除本地dev分支
git branch -d dev 

merge 和 rebase

创建冲突场景

# 新建文件夹,初始化为Git仓库
mkdir learn-git
cd learn-git
git init

# 添加并编辑文件 
vim c2

# 添加文件到暂存区
git add c2

# 提交commit -m 代表添加一个“提交信息”
git commit -m "c2"

# 新建并跳转到experiment分支
git switch -c experiment

# 添加并提交c4
vim c4
git add c4
git commit -m "c4"

# 切换回master分支
git switch master

# 添加并提交c3
vim c3
git add c3
git commit -m "c3"

到这c2就产生了分叉,experiment分支推进到了c4,master分支推进到了c3
这个时候如果想把两个分支的修改合并到master分支上,可以使用merge或rebase(变基),两种方式最后合并的结果是一样的,但rebase不会产生分叉,rebase的提交历史也比merge更线性

merge

# 使用merge方式合并分支
# 先切换到master分支
git switch master

# 合并分支(会弹出commit message的编辑框,:wq 保存退出)
git merge experiment

# 查看分支合并情况
git log --graph --pretty=oneline --abbrev-commit

--- merge示意图 引用自《Git Pro》

使用merge合并分支,相当于三方合并,合并c2,c3,c4(未新建experiment分支前的修改c2、新建分支后master分支的修改c3、experiment分支的修改c4)

直接使用git merge <要被merge的分支名> ,没有冲突的情况下默认使用参数:--f 即:Fast-forward(快进式合并)
推荐使用--no-ff 即:git merge --no-ff <要被merge的分支名>
这个参数的意思是禁止快进式合并,合并时会自动创建一次commit提交,保证提交链的完整性
而Fast-forward合并分支会丢掉分支信息

rebase

# 使用rebase方式合并分支
# 先切换到experiment分支
git switch experiment

# rebase分支
git rebase experiment

# 先切换到master分支
git switch master

# 将experiment合并到master
git merge experiment

# 查看分支合并情况
git log --graph --pretty=oneline --abbrev-commit


--- rebase示意图 引用自《Git Pro》

rebase的原理是:找到c3和c4共同的祖先c2,暂存共同祖先c2到当前分支(expriment)的修改内容,然后将分支指向master的c3,并应用之前暂存的修改内容
我们可以这么理解:

rebase就是先把其他分支(master)已经提交的代码(c3)放到前面,把当前分支(experiment)提交的修改(c4)放到后面,这样做的好处就是:自己写代码(experiment分支上的)将出现在master最新的一次commit中,一目了然

rebase:黄金法则:绝对不要在公共分支使用rebase,rebase会重写提交历史

参考资料

ssh-keygen的-C后面的邮箱有什么用?
Git 合并时 --no-ff 的作用
记Git报错-refusing to merge unrelated histories

原文地址:https://www.cnblogs.com/aaronlinv/p/13611307.html