git操作
假设远程仓库中有main分支,其中有Init的commit
首先克隆同步到本地仓库,git clone https://github.com/xx/xx.git
为了不扰乱main分支,应该在本地仓库中创建新的分支git checkout -b my-feature
后续在此分支上进行自己的代码修改,修改完成后,使用git diff
查看修改的代码,然后可git add .
添加修改到暂存区(staging)并告知本地git,git commit -m "f-commit"
提交commit给local git
git push -u origin my-feature
同步到远程仓库,此时远程仓库中也会新增my-feature
分支
如果此时远程仓库的代码有更新,则需要先拉取远程仓库main到本地的main,先切换到main分支git checkout main
,值得注意的是,这时候disk中的代码是Init状态的代码,并非在f-commit
下的代码
这时候使用pull拉取git pull origin main
,这时本地仓库与远程仓库状态一样,都有两个分支,切换回my-feature分支,为了在此分支上同步main分支代码更新,使用git rebase main
,先让main的最新修改与当前分支同步,在这个基础上尝试添加该分支之前的commit(即f-commit
),如果有rebase conflict
,需要手动选择保留哪个修改,这时候my-feature分支上会在f-commit前插入与远程分支一样的update commit
再将本地同步到远程,git push -f origin my-feature
,push需要加-f表示强制push,因为此时远程仓库的my-feature分支同样也有Init,update和f-commit三个commit
将my-feature分支合并到main分支中pull request
使用squash and merge
,将一个分支上的所有改变合并成一个commit,合并完成后删除远程的my-feature分支,同样在本地仓库上git checkout main
切换到main分支再git branch -D my-feature
删除my-feature,最后在main分支上git pull origin main
同步远程仓库的更新,如此反复
以上内容来源于https://www.youtube.com/watch?v=uj8hjLyEBmU
关于撤销
假设初始状态下四个区域一致,disk是硬盘,staging暂存区,local本地仓库以及远端仓库remote
如果发生修改change,但并未进行git add
等操作,也就是说只在硬盘上修改,如果想要撤销,可以使用git checkout <changed_file>
或者git restore <changed_file>
直接回退到Init状态,也就是上一次commit这个文件的状态,新版本的git更推荐使用restore
在git add 后,也就是修改被同步到暂存区”git status -> Changes to be commited”,如果想要撤销在暂存区的修改而保留硬盘上的修改,也就是取消git add的效果,就可以使用git reset <changed_file>
或者git restore --staged <changed_file>
如果想要连同硬盘上的修改也撤销,可以使用git checkout HEAD <changed_file>
表示将文件撤销到最近一次commit的状态(HEAD)
在git commit后,修改被提交到了本地git中,如果仅撤销本地git的修改,即取消git commit的效果,则可以使用git reset --soft HEAD~1
,因为HEAD表示最近的一次commit,所以这里使用HEAD~1
来表示想要回退到的Init状态
进一步,如果想要取消连同取消git commit 和 git add 的效果,只保留在硬盘上的修改,那么可以使用git reset HEAD~1
进行实现,也可以使用git reset --mixed HEAD~1
要是连硬盘上的修改也撤销,就可以使用git reset --hard HEAD~1
另一种撤销git revert,本质上是通过添加一个新的commit,使得看起来将change删除了,git revert HEAD
这里的HEAD就是指commit过的change
使用revert的好处有1. 可以撤销中间提交的任意一个commit
2.当修改push到远端remote仓库后,想要撤销公有分支上的修改,那么就只能使用revert,然后再push到远端仓库,从结果上撤销这个修改,否则会令使用这个公有分支的开发者混乱;也有可能这个分支是私有分支,就可以使用git reset --hard HEAD~1
并推送到远端git push -f
,-f 就是让remote强行接受这个分支变化,但不能用在共有分支上