【工具】Git
Dandelion 4/25/2022 tool
# 概述
2005 年,Linus 花了两周用 C 语言写成了 Git!(版本控制系统:分布式 VS 集中式)
重要概念:工作区 & 版本库(暂存区 stage、master、HEAD)
# 本地仓库
git 的安装
git config --global user.name "Your Name" git config --global user.email "email@example.com"
1
2git 的基本使用
mkdir directory cd directory pwd // 打印当前目录 git init ls -ah // 查看当前目录下的文件,包括隐藏文件 touch readme.txt git add readme.txt // 可以多次add,一次commit git commit -m "write a readme file" git status git diff readme.txt // 查看具体的修改
1
2
3
4
5
6
7
8
9
10查看版本日志
git log // 查看当前版本之前的历史提交记录(穿越过去) git log --pretty=oneline // 简单输出 git reflog // 查看所有的历史提交记录(重返未来)
1
2
3版本回退
git reset --hard HEAD^ // 回退到上一个版本 cat readme.txt // 查看文件内容 git reset --hard commit_id // 版本号不用写全
1
2
3工作区/版本库
git diff HEAD -- readme.txt // 查看工作区和版本库里面最新版本的区别 git checkout -- readme.txt // 丢弃工作区的修改(两种情况:readme.txt是否已在暂存区,最近的状态) git reset HEAD readme.txt // 将add进暂存区的文件,重新放回工作区
1
2
3删除文件
git add test.txt git commit -m "add test.txt" rm test.txt git status git rm test.txt git commit -m "remove test.txt" 或 git checkout -- test.txt // 把误删的版本恢复到版本库中的最新版本,即用版本库里的版本替换工作区的版本
1
2
3
4
5
6
7
8
# 远程仓库
远程仓库连接
git remote add origin git@github.com:xxx/xxx.git // 添加并绑定远程仓库,远程库的名字就是origin git push -u origin master // 把本地库的所有内容推送到远程库(第一次推送master分支时,加-u的作用:关联本地和远程的master分支) git push origin master // 往后的推送
1
2
3断开与远程仓库的连接
git remote -v // 查看远程库信息 git remote rm origin // 解除本地和远程的绑定关系
1
2从远程库克隆
git clone git@github.com:xxx/xxx.git // 创建远程库,并克隆到本地
1
# 分支管理
注意:HEAD 指向的是当前分支。推荐使用分支完成某个任务,合并后再删除。
分支操作—checkout
git checkout -b dev // 创建并切换到分支dev,相当于以下两条命令 git branch dev git checkout dev git branch // 列出所有分支,当前分支前加* ...... Do something on dev ...... git checkout master // 切换回主分支 git merge dev // 把dev分支的工作成果合并到master分支,快进模式(Fast-forward) git branch -d dev // 删除dev分支 git branch
1
2
3
4
5
6
7
8
9分支切换—switch
git switch -c dev // 创建并切换到分支dev git switch master // 切换到主分支
1
2冲突解决
git merge dev // 合并dev和master分支,发生冲突 git status // 查看发生冲突的文件 cat readme.txt // 修改冲突文件,<<<<<<<,=======,>>>>>>> git add readme.txt git commit -m "conflict fixed" // 再次提交 git log --graph --pretty=oneline --abbrev-commit // 查看分支合并情况 git branch -d dev
1
2
3
4
5
6
7分支管理
git switch -c dev git add readme.txt git commit -m "add merge" git switch master git merge --no-ff -m "merge with no-ff" dev git log --graph --pretty=oneline --abbrev-commit
1
2
3
4
5
6通常,合并分支时,如果可能,Git 会用 Fast forward 模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用 Fast forward 模式(--no-ff),Git 就会在 merge 时生成一个新的 commit,这样,从分支历史上就可以看出分支信息。Bug 分支
考虑场景:正在 dev 分支上进行开发,突然接到立即修复 bug 的任务,但工作尚未完成不能提交。
git stash // 隐藏当前工作区,等以后恢复现场后继续工作 git status // 干净的工作区 在master分支上,创建分支来修复bug git checkout master git checkout -b issue-101 // 创建并切换到临时分支 ...... fix the bug, add, commit ...... git switch master git merge --no-ff -m "merged bug fix 101" issue-101 // 合并bug,并删除issue-101分支 git switch dev // 继续回到dev分支干活 git status git stash list // 列出保存的工作区现场 恢复工作现场 git stash apply & git stash drop // 恢复并删除stash内容 git stash pop git stash apply stash@{0} // 恢复指定的stash 注意:到目前为止,master上的bug被修复,而dev是更之前的分支,其上也存在相同的bug,且还未被修复。 git branch // dev 分支 git cherry-pick 4c805e2 // 复制一个特定的提交到当前分支(4c805e2为bug修复的提交id),自动为dev分支做了一次提交 也可以直接在dev分支上修复bug,再切回master“重放”这个修复过程,依旧需要保存现场。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19Feature 分支
每添加一个新功能,最好新建一个 feature 分支,在上面开发,完成后合并,最后删除该 feature 分支。
git branch -D feature // 强行删除一个没有被合并过的分支 // 其他操作跟Bug分支类似
1
2多人协作
git remote // 查看远程库的信息 git remote -v // 查看远程库的详细信息 git push origin master // 向远程库推送主分支(主分支要时刻与远程同步) git push origin dev // 向远程库推送其他开发分支(开发分支也要时刻与远程同步) bug分支只用于在本地修复bug,没必要推到远程; feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。 git checkout -b dev origin/dev // 创建远程origin的dev分支到本地 git add env.txt git commit -m "add new env" git push origin dev 发现提交的新修改存在冲突 git branch --set-upstream-to=origin/dev dev // 指定本地dev分支与远程origin/dev分支的链接 git branch --set-upstream branch-name origin/branch-name git pull // 抓取origin/dev上的最新提交到本地 手动解决冲突,add,commit,最后push
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Rebase:可以把本地未 push 的分叉提交历史整理成直线
git rebase // 把分叉的提交历史“整理”成一条直线,看上去更直观 git log --graph --pretty=oneline --abbrev-commit // 本地提交记录是一条直线 git push origin master git log --graph --pretty=oneline --abbrev-commit // 本地和远程提交记录都是一条直线
1
2
3
4
# 标签管理
标签,即版本库的一个快照,发布版本时通常会在版本库中打一个标签。
创建标签
git branch git checkout master // 在主分支上打标签 git tag v1.0 // 为最新的提交打标签 git tag // 查看所有标签(按字母排序) git log --pretty=oneline --abbrev-commit // 查看提交历史 git tag v0.9 f52c633 // 为指定提交打标签 git show v0.9 // 查看标签信息 git tag -a v0.1 -m "version 0.1 released" 1094adb // 创建带有说明的标签
1
2
3
4
5
6
7
8操作标签
git tag -d v0.1 // 删除标签,标签存储在本地 git push origin v1.0 // 推送某个标签到远程 git push origin --tags // 一次性推送全部尚未推送到远程的本地标签 删除远程标签 git tag -d v0.9 // 本地删除 git push origin :refs/tags/v0.9 // 同步远程 登录GitHub,查看标签是否删除
1
2
3
4
5
6
7
# GitHub 和 Gitee
如何参与开源项目?
- Fork 某个开源项目
- git clone git@github.com:xxx/xxx.git // 从自己的账号下 clone(避免没有推送权限)
- 修复 bug 或新增功能后,在 GitHub 上发起一个 pull request,代码贡献
Gitee 使用
git remote -v git remote rm origin git remote add origin git@gitee.com:xxx/xxx.git git remote rm origin git remote add github git@gitee.com:xxx/xxx.git git remote add gitee git@gitee.com:xxx/xxx.git git remote -v git push github master git push gitee master
1
2
3
4
5
6
7
8
9
# Git 自定义
git config --global color.ui true // 让Git显示颜色,会让命令输出看起来更醒目
https://github.com/github/gitignore // 配置文件
忽略文件:.gitignore,把要忽略的文件名填进去。要放到版本库
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
# My configurations:
db.ini
deploy_key_rsa
# 不排除.gitignore和App.class:
!.gitignore
!App.class
git add -f App.class // 强制添加到Git
git check-ignore -v App.class // 查看忽略文件中的哪个规则使添加失效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 场景举例
- case 1
- 描述:在本地修改完成已 push 至远程后,想要撤销这次的 push。(本地修改不变/回退到上个版本,远程退回到上次 push 的版本)
- 解决:reset 不产生新 commit,只是改变当前 HEAD 指向的 commit
- 不删除工作空间改动代码,撤销 commit,不撤销 git add:
git reset --soft 版本号
- 删除工作空间改动代码,撤销 commit,撤销 git add:
git reset --hard 版本号
- 最后强制提交当前版本,以撤销仓库远程版本号:
git push origin master -–force
- 不删除工作空间改动代码,撤销 commit,不撤销 git add:
- case 2
- 描述:依次向远程提交了三个版本(版本 1,2,3)后,突然发现版本 2 不行,想要撤销版本 2,又不想影响版本 3 的提交。
- 解决:revert
- case 3
- 描述:批量修改 commit 注释
- 解决:rebase
- 打开编辑窗口:
git rebase -i HEAD~n
- 批量修改 pick 为 r (opens new window):
:.,$s/pick/r/g
- 保存退出,依次修改 commit 信息
- 强制推送到远程仓库:
git push origin dev -f
- 打开编辑窗口:
- case 4
- 描述:同步远程代码
- 解决:fetch vs pull( git pull = git fetch + git merge/rebase )
- case 5
- 描述:修改分支名
- 解决:分支重命名 (opens new window)
- 切换到旧分支:
git checkout old_branch
- 更新旧分支与远程分支一致:
git pull origin old_branch
- 重命名分支:
git branch -m old_branch new_branch
- 将本地新分支推送到远程:
git push --set-upstream origin new_branch
- 将远程旧分支删除:
git push origin --delete old_branch
- 切换到旧分支:
- case 5
- 描述:删除分支
- 解决:--delete/-d
- 删除本地分支:
git branch -d <branch_name>
- 删除远程分支:
git push origin --delete <branch_name>
- 删除本地分支: