概述
先学会GIt命令以及原理概念,再学IDEA中如何使用Git。
概念
0x01 四大区域
工作区、版本库、暂存区、远程仓库。
工作区(Working Directory):可见的代码项目目录。
版本库(commit History):.git目录。
暂存区(Stage或Index):英文stage或index。位置在目录.git/index。
add到暂存区、commit到版本库、push到远程仓库。
0x02 三大还没想好叫啥名的模块(commit、tree、blob)
一个commit对应一个tree。一个tree对应一个目录。
blob和文件名无关,文件内容相同就对应一个blob。
命令
提交代码
git add # 添加到暂存区
git commit # 提交版本库
git push # 推到远程仓库
代码恢复
git reset --soft # 暂存区 -> 工作区
git reset --mixed # 版本库 -> 暂存区
git reset --hard # 版本库 -> 暂存区 -> 工作区
git reset -- files # 版本库 -> 暂存区
git checkout -- files # 暂存区 -> 工作区
对比命令
git diff # 工作区和暂存区
git diff head # 工作区和版本库
git diff --cached # 暂存区和版本库
查看
git status
git log
git remote -v # 查看远程仓库
# 取消追踪但是不删除本地文件
git rm -r --cached .
git rm --cached readme1.txt
分支管理
分支创建与切换
#新版Git
git switch -c dev
git switch dev
#老版
git checkout -b dev
git checkout dev
分支切换额外
//TODO
git stash
git stash save "save tmp maven"
git stash apply
git revert
git reset
分支合并
rebase
git merge foo
git merge foo --squash #
git merge foo -no-ff #将foo分支合并过来,有merge commit记录。
git rebase master #危险!多人维护,会改变历史导致别人commit丢失
rebase冲突解决步骤
git rebase foo
# 解决冲突文件
git add .
git rebase --continue
# 如果还有冲突就解决后继续continue
删除分支
删除本地分支
git branch -d foo
# 删除远程分支
git push origin --delete <branchName>
cherry-pick
https://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html
远程仓库
git remote -v #查看远程仓库
git remote add origin git@server-name:path/repo-name.git #添加一个远程库
git remote show origin
git remote rm [remote-name]
git remote rename [foo-remote-name] [bar-remote-name]
git pull = git fetch + git merge
切换仓库后要把分支挂在到远程分支
git branch --set-upstream-to=origin/<branch> master
分支管理
git checkout -b dev origin/dev #创建远程origin的dev分支到本地,并命名为dev
git checkout origin/dev --track #与上面效果一样
历史管理
版本回退
git reset --hard HEAD^ #回退到上一个版本
git reset --hard cb926e7 #回退到具体某个版
git reflog #查看命令历史,常用于帮助找回丢失掉的commit
git rebase -i 合并历史多次commit
git rebase -i HEAD~4 #合并最近4此commit
原理
git status
当执行 “git status” 命令扫描工作区改动的时候。
先依据 .git/index 文件中记录的(工作区跟踪文件的)时间戳、长度等信息判断工作区文件是否改变。
如果工作区的文件时间戳改变,说明文件的内容可能被改变了,需要打开文件,读取文件内容,和更改前的原始文件相比较(本地文件和与之对应的object库中的文件的内容进行对比),判断文件内容是否被更改。
如果文件内容没有改变,则将该文件新的时间戳记录到 .git/index 文件中。因为判断文件是否更改,使用时间戳、文件长度等信息进行比较要比通过文件内容比较要快的多,所以 Git 这样的实现方式可以让工作区状态扫描更快速的执行,这也是 Git 高效的因素之一。
备忘
MacOS下git的ssh挂代理
~/.ssh/config
Host github.com
User git
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
unrelated histories问题
fatal: refusing to merge unrelated histories
git pull origin master --allow-unrelated-histories
git branch -m oldName newName
代理设置
git http代理设置
git config --global http.proxy socks5://127.0.0.1:1080
git config --global https.proxy socks5://127.0.0.1:1080
git config http.proxy socks5://127.0.0.1:1080
git config https.proxy socks5://127.0.0.1:1080
# 只对github进行代理
git config --global http.https://github.com.proxy https://127.0.0.1:1080
git config --global https.https://github.com.proxy https://127.0.0.1:1080
git config --unset http.proxy
git config --unset https.proxy
git ssh代理设置
修改 ~/.ssh/config 文件(不存在则新建):
# 必须是 github.com
Host github.com
HostName github.com
User git
# 走 HTTP 代理
# ProxyCommand socat - PROXY:127.0.0.1:%h:%p,proxyport=8080
# 走 socks5 代理(如 Shadowsocks)
ProxyCommand nc -v -x 127.0.0.1:1080 %h %p
也可以设置全局环境变量
export ALL_PROXY 'socks5://127.0.0.1:1080'
学习资料
Pro Git book v2
猴子都能懂的Git入门
Github and Git 图文教程
Git图文教程及详解
https://www.cnblogs.com/qdhxhz/p/9757390.html
https://www.jianshu.com/p/c17472d704a0
https://blog.csdn.net/jack_nichao/article/details/51702571
三路合并问题
两个分支合并要先寻找公共祖先,要是和公共祖先都不一样才会出现冲突。
https://blog.csdn.net/weixin_33757911/article/details/88773046
https://marsishandsome.github.io/2019/07/Three_Way_Merge
https://www.jianshu.com/p/e8932999fe1f