本文为历时1年多整理的吐血原创,请勿原文转载,引用请贴出出处。
一、项目使用
1.1 git 从远程服务器更新本地项目
从远程服务器上更新别人上传的文件
1.使用git fetch更新,相当于是从远程获取最新版本到本地,不会自动merge
git fetch origin master
git log -p master..origin/master
git merge origin/master
首先从远程的origin的master主分支下载最新的版本到origin/master分支上
然后比较本地的master分支和origin/master分支的差别
最后进行合并
上述过程其实可以用以下更清晰的方式来进行:
git fetch origin master:tmp
git diff tmp
git merge tmp
从远程获取最新的版本到本地的tmp分支
之后再进行比较合并
2.使用git pull 更新,相当于是从远程获取最新版本并merge到本地
git pull origin master
上述命令其实相当于git fetch 和 git merge
在实际使用中,git fetch更安全一些
因为在merge前,我们可以查看更新情况,然后再决定是否合并
3. idea下的操作和vs工程文件的更新
idea打开源码目录后,记得,exclude build等无关目录。
使用idea中集成的git插件,同步远程仓库的最新修改到本地。
在上面操作完后,直接使用cmake-gui选中源码,选中build目录。然后config, generate重新生成下.sln(防止新生成的文件,加载不上去)。
打开的.sln文件,将会发现,书签还是有效的。
1.2 撤销已经commit但是还没有push的操作(2020.4.23)
找到之前提交的git commit的 commit_id, commit_id为类似于“51ec2ec6926822435edddd0b9680f3d8329c137b”的一组字符串。
git log
找到想要撤销的commit_id。选择要commit_id时,此时如果需要恢复到 test2的话,则test2之后,到第一个"update 2020.04"之间的更新都将消失。所以,如果两次"update 2020.04"的有问题,需要恢复到第一次"update 2020.04"commit之前的状态时,则此处需要选中第一个"update 2020.04"的commit_id。
否则,选错了commit_id,将会让你看到更新的大规模丢失。不过不要慌乱,还是可以恢复的,但如果你删除了本地的.git文件夹(任何时候都不要删除它),那就回天乏力了。
git reset --soft commit_id
完成撤销,同时将代码恢复到前commit_id 对应的版本,强制回滚到之前的版本。
git reset commit_id
完成撤销,停留在当前版本,不对代码修改进行撤销,可以直接通过git commit重新提交对本地代码的修改。
执行 git log 查看,commit提交已撤销。
rehead的几种区别
1.3 删除远程的文件或文件夹
原因有很多,如错传了保密的文件到git,需要删除,但希望本地保留。或者由于本地修改了文件夹大全名大小写的原因,同步到git上并不区分大小写,造成了一些文件同步不了,所以要先把git远程库上文件夹删除掉,然后再重新同步。如,我把dirs里的全部移除,但是本地文件还保留。
git rm -r -n --cached */dirs/* # -n:加上这个参数,执行命令时,是不会删除任何文件,而是展示此命令要删除的文件列表预览。 git rm -r --cached */dirs/* # 最终执行命令. git commit -m "移除dirs目录下所有文件" # 提交 git push origin master # 提交到远程服务器 |
1.4 错add的撤销
git add 添加 多余文件
这样的错误是由于, 有的时候 可能
git add . (空格+ 点) 表示当前目录所有文件,不小心就会提交其他文件
git add 如果添加了错误的文件的话
撤销操作
git status 先看一下add 中的文件
git reset HEAD 如果后面什么都不跟的话 就是上一次add 里面的全部撤销了
git reset HEAD XXX/XXX/XXX.java 就是对某个文件进行撤销了
1.5 撤销push
1) 执行 git log查看日志,获取需要回退的版本号
2) 执行 git reset –-soft <版本号> ,如 git reset --soft 4f5e9a90edeadcc45d85f43bd861a837fa7ce4c7 ,重置至指定版本的提交,达到撤销提交的目的
然后执行 git log 查看
此时,已重置至指定版本的提交,log中已经没有了需要撤销的提交
git log后,需要退出vim,按Q即可。
git reset 命令分为两种: git reset –-soft 与 git reset –-hard ,区别是:
前者表示只是改变了HEAD的指向,本地代码不会变化,我们使用git status依然可以看到,同时也可以git commit提交。后者直接回改变本地源码,不仅仅指向变化了,代码也回到了那个版本时的代码。
3) 执行 git push origin 分支名 –-force ,强制提交当前版本号。
如,
git push origin master --force
一定要force,否则下次修改提交后,提示会让你merge,这样你要回退远程服务器上的v1_3_1的提交就失败了。
至此,撤销push提交完成。
完整的回退操作过程:
git push origin master --force
此时,刷新下idea,将会发现,之前v1.3.1提交的修改,又返回去了,而且v1.3.1之后的修改,也没有消失。
1.6 git rebase, cherry-pick
git cherry-pick
git cherry-pick 可以选择某一个分支中的一个或几个commit(s)来进行操作。例如,假设我 们有个稳定版本的分支,叫v2.0,另外还有个开发版本的分支v3.0,我们不能直接把两个分支合并,这样会导致稳定版本混乱,但是又想增加一个v3.0 中的功能到v2.0中,这里就可以使用cherry-pick了。
# 先在v3.0中查看要合并的commit的commit id
git log
# 假设是 commit f79b0b1ffe445cab6e531260743fa4e08fb4048b
# 切到v2.0中
git check v2.0
# 合并commit
git cherry-pick f79b0b1ffe445cab6e531260743fa4e08fb4048b
git merge是用来合并两个分支的。
# 将b分支合并到当前分支
git merge b
假设现在有两zd个分支 A B
1) 在B分支上执行内 git merge A 后 A就被合到B上了
2) 在B分支上执行 git rebase A 后,效果与merge是一样的,但是 A就没有了,两个分容支就合在一起了。
git rebase有点类似git merge,但是两者又有不同,打个比方,你有两个抽屉A和B,里面都装了衣服,现在想把B中的衣服放到A中,git merge是那种横冲直撞型的,拿起B就倒入A里面,如果满了(冲突)再一并整e799bee5baa6e4b893e5b19e31333337373566理;而git rebase就很持家了,它会一件一件的从B往A中加,会根据一开始放入的时间顺序的来加,如果满了你可以处理这一件,你可以继续加,或者跳过这一件,又 或者不加了,把A还原。所以merge适合那种比较琐碎的,简单的合并,系统级的合并还是用rebase吧。
专业的区别请移步到这里合并和衍合
# 合并b
git rebase b
# 处理完冲突继续合并
git rebase –continue
# 跳过
git rebase –skip
# 取消合并
git rebase –abort
1.7 git stash
应用场景:
1 当正在dev分支上开发某个项目,这时项目中出现一个bug,需要紧急修复,但是正在开发的内容只是完成一半,还不想提交,这时可以用git stash命令将修改的内容保存至堆栈区,然后顺利切换到hotfix分支进行bug修复,修复完成后,再次切回到dev分支,从堆栈中恢复刚刚保存的内容。
2 由于疏忽,本应该在dev分支开发的内容,却在master上进行了开发,需要重新切回到dev分支上进行开发,可以用git stash将内容保存至堆栈中,切回到dev分支后,再次恢复内容即可。
总的来说,git stash命令的作用就是将目前还不想提交的但是已经修改的内容进行保存至堆栈中,后续可以在某个分支上恢复出堆栈中的内容。这也就是说,stash中的内容不仅仅可以恢复到原先开发的分支,也可以恢复到其他任意指定的分支上。git stash作用的范围包括工作区和暂存区中的内容,也就是说没有提交的内容都会保存至堆栈中。
具体,参考0423 git stach的使用
1.8 迁移代码到另一个远程git仓库
不保留log等提交的记录的迁移就不说了,soeasy!
目标:把A仓库的代码迁移到B仓库并且保存所有的git log,B仓库已经存在了哦,哪怕是个空仓库。
再说这个之前先说点其他。在使用git的时候我们可能见到这样的命令。不想看解说想直接看步骤的往下翻
git pull origin master //拉取远程master分支的代码
git push origin master //把代码推到远程master分支上去
有没有人好奇为什么是origin,而不是其他名字,比如git pull orginal master或者git pull origin2 master;
解答上面的问题很简单,请在你的工程中输入
git remote
发现了什么呢?默认就有一个origin,代表远程仓库。origin是有地址,地址就是当前仓库的git地址,是个url哦。所以为什么git push origin master就自动相应的推到的远程仓库的master分支了。
下面是正确的操作步骤 (看准情况分类很重要,就两种)
不管哪种情况请从情况1开始看哈哈:
情况1:
B仓库是一个空仓库,除了默认的master分支,没有任何分支。把A的branch1,branch2,branch3...依次迁入B,B也就有branch1,branch2,branch3,
- 进入A工程
- git remote
原因:看下当前远程仓库有啥名字,然后取个崭新的、不重复的名字,名字是过渡,不必纠结取啥名字因为名字不是关键绑定的url才是,看下一步。这里取名origin2
- git remote add origin2(这替换你自己心目中的名字) master
不纠结照抄这就话
- git remote set-url origin2 git@git.hub.com:B.git
原因:后面的B仓库地址url才是关键,origin2只是过渡,百人百种起法
- 进入A工程的branch1分支上
- git pull
原因:拉取一下最新代码
- git checkout -b branchB1
原因:branchB1是基于A工程branch1开的新分支,代码跟A工程branch1一毛一样,但是这个名字branchB1非常重要,非常重要,原因只有一个:这个分支会被推到B工程,结果就是B工程下面就有这个分支。所以你懂的,万一你的B工程下面已经有了该分支名字,你这个做了好多工作的branchB1是根本推不上去的,是不是很疯狂
- git push origin2
结果:这一步能不能成功就看上一步,不多说,就看你取名字瞎不瞎
如果上面的结束,说明已经成功迁移出一个分支了。常见问题:
疑问1:问其他的分支怎么做,请重复
- 进入A工程的branch2分支上
- git pull
- git checkout -b branchB2
- git push origin2
branch2 变成branchB2然后被推到B仓库
疑问2:你还问我第三个分支怎么迁移,不解释啦实在不行哎我还能说啥。
疑问3: 我打眼一看B工程中的分支名字都是branchB1,branchB2....怎么破,
改分支的名字直接登陆git.hub.com,打开工程你会看到branches这个,点进去可以修改.至于改名字,代码都迁移过去了,改个名字还很远吗
情况2:
B仓库不是一个空仓库,里面各种各样乱七八糟的分支。把A的branch1,branch2,branch3...依次迁入B,B也就有branch1,branch2,branch3,
呃呃呃呃呃,
步骤跟上面一毛一样,能不能推成功,就看你起名字的功夫了。什么名字,就是你最后要推到B工程上去的分支名字,注意部分就是上面疑问1的地方
1.9 git 下载项目(zip)后,关联远程仓库 (事后关联)
前期网速不佳,下载了zip,期间又修改了源码,后期需要重新关联远程仓库,拉取新的修改。
方案1
- Grab the .git directory by cloning a bare
repository
$ mkdir repo
$ git clone --bare http://github/user/repo repo - Make the .git directory and move the cloned
files
$ mkdir repo/.git
$ mv repo/* repo/.git - Unzip the
repository
$ unzip repo.zip - Re-initialize the
repository
$ cd repo
$ git init - Verify you're
sync'ed
$ git pull - Reset the HEAD to
clean up the status
$ git reset HEAD
方案2 (推荐)
unzip <repo>.zipgit
cd <repo>
git init
git add .
// git commit -m "my modify" // 如果自己修改了部分,可以这样先提交自己的修改
// 如果自己没有修改,直接就git clone好了,不要使用本方案2了。
git remote add origin https://github.com/<user>/<repo>.git
git remote update
git checkout master
Just make sure to replace <user> & <repo> with your github user name and your repo name ;)
方案3
第一步: 初始化空的git本地仓库
git init
第二步:添加所有文件
git add .
第三步:提交所有文件到本地仓库
git commit -m "xxx"
第四步:关联远程仓库
git remote add origin “远程仓库”
第五步:本地项目推送远程仓库
git push -u origin master
五步之后即可完成关联
1.10 项目的在线依赖库
下载
当git clone下来了一个项目,但是后来cmake的时候,发现有些在线依赖库没有被下载下来。如何补救?
cd 到相应的第三方库目录下,然后执行:
git submodule update --init --recursive
Cheetah@Cheetah-PC MINGW64 / $ cd /e/Projs/algs/cc/CloudCompare/extern/CCCoreLib/
Cheetah@Cheetah-PC MINGW64 /e/Projs/algs/cc/CloudCompare/extern/CCCoreLib (master) $ git submodule update --init --recursive Submodule 'extern/CCCoreLib' (https://github.com/CloudCompare/CCCoreLib.git) registered for path './' Submodule 'plugins/core/IO/qE57IO/extern/libE57Format' (https://github.com/asmaloney/libE57Format) registered for path '../../plugins/core/IO/qE57IO/extern/libE57Format' Submodule 'plugins/core/Standard/qPoissonRecon/PoissonReconLib' (https://github.com/cloudcompare/PoissonRecon) registered for path '../../plugins/core/Standard/qPoissonRecon/PoissonReconLib' Cloning into 'E:/Projs/algs/cc/CloudCompare/extern/CCCoreLib'... Cloning into 'E:/Projs/algs/cc/CloudCompare/plugins/core/IO/qE57IO/extern/libE57Format'... Cloning into 'E:/Projs/algs/cc/CloudCompare/plugins/core/Standard/qPoissonRecon/PoissonReconLib'... Submodule path './': checked out 'bb858fa089134e008750e0d1e02f7dd3fd87412c' Submodule path '../../plugins/core/IO/qE57IO/extern/libE57Format': checked out '14f6a67cf98485189cfd154bc42081d38e480b9d' Submodule path '../../plugins/core/Standard/qPoissonRecon/PoissonReconLib': checked out '134fb831764dd5ebd53616e83992f0060e4b09ce'
Cheetah@Cheetah-PC MINGW64 /e/Projs/algs/cc/CloudCompare/extern/CCCoreLib ((bb858fa...)) |
或者,事先已经发现缺失了某个库,git clone时使用如下命令操作。
git clone --recursive https://github.com/influxdata/influxdb-java.git
添加第三方库的依赖
真正项目开发过程中避免不了要使用第三方的库或模块,或者自己开发过的模块需要引用到其他业务里面,避免重复开发,简单的办法把模块仓库当成主项目的子仓库。
git submodule git submodule add git://xxxxx.git findername git submodule status git submodule update |
1.11 使fork项目与源项目保持一致方法
github上经常干的一件事情是看到好的项目,总会fork到自己的项目列表里,但是源项目如果更新了,怎么同步到我们自己的fork项目呢?
操作如下:
- 先clone自己的fork项目到本地工程目录, git clone git@gitlab.alibaba-inc.com:riqi/{project}.git
- 进入该项目目录,添加别名并指向源项目,git remote add {project} git@gitlab.alibaba-inc.com:{group}/{project}.git
- 拉取源项目的master主干代码并自动合并到本地fork的master主干代码,git pull {project} master
- 合并成功后,将合并后的代码推送到自己的fork项目master主干代码,git push
以上4个步骤,即可轻松更新自己的fork项目同源项目master主干代码保持一致!
1.12 切换远程仓库地址
git remote-v 显示所有的远程地址
或,git remote 查看所有远程仓库, git
remote xxx 查看指定远程仓库地址
# git remote rm origin
# 方法1 (推荐)
git remote add origin2
git@github.com:tyyking/sharding-sphere-demo.git
# 方法2 (直接覆盖原来的orign,慎用)
git remote set-url git@github.com:tyyking/sharding-sphere-demo.git
# 方法3
进入git_test/.git,修改config中的【remote "origin"】里的url。
Git check某个分支
git clone -b devel https://github.com/cnr-isti-vclab/vcglib.git vcg
1.13 合并分支
情况是这样的,我之前将本地的代码,commit到了master。但是远程是devel分支(默认分支)。我执行 1.9 小节的方案2时,checkout devel后,发现之前的修改都x消失掉了。
所以,我可以chechout master,可以看到自己的修改,但是无法和远程origin/devel关联了。所以,我再checkout devel默认分支。然后,执行merge:
git merge --allow-unrelated-histories master
注意:没有后面的 --allow … 的内容,将提示“ fatal: 拒绝合并无关的历史”。
1.14 在线fork的项目更新
为什么不在本地操作,而直接在github上操作,主要是因为自己的更改的部分小,无需下载到本地,再pull到自己的origin maste分支上。
(1) 打开fork 过来的项目, 点击new pull request
(2)在进入的界面, 后进行将左边的设置为你自己的仓库, fork 过来的源在右边。
接下来, 将其展示出可以调整状态: 右边改为源fork地址
就会出现变更数据
点击create pull request
1.15 项目分支管理
命令 |
|
得到结果 |
说明 |
git branch |
当前所有分支的一个列表 |
$ git branch |
注意 master 分支前的 * 字符:它代表现在检出的那一个分支(也就是说,当前 HEAD 指针所指向的分支)。 这意味着如果在这时候提交,master 分支将会随着新的工作向前移动。 |
git branch -v |
查看每一个分支的最后一次提交 |
$ git branch -v |
|
git branch --merged |
|
|
--merged 与 --no-merged 这两个有用的选项可以过滤这个列表中已经合并或尚未合并到当前分支的分支。 如果要查看哪些分支已经合并到当前分支,可以运行 git branch --merged。 |
git branch --no-merged |
|
|
这里显示了其他分支。 因为它包含了还未合并的工作,尝试使用 git branch -d 命令删除它时会失败。果真的想要删除分支并丢掉那些工作,如同帮助信息里所指出的,可以使用 -D 选项强制删除它。 |
git branch -r |
查看远程分支 |
$ git branch -r origin/HEAD -> origin/master origin/feature/IOS_visualtrack origin/feature/android_visualtrack origin/master |
|
git branch -a |
查看所有分支 |
|
git branch -r 无法获取远程分支,ui可以看见分支但是git 命令无法查看 原因 git branch -a 这条命令并没有每一次都从远程更新仓库信息,我们可以手动更新一下。 git fetch origin git branch -a |
git checkout -b myRelease origin/Release |
切换远程分支 |
$ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/Release remotes/origin/master
$ git checkout -b myRelease origin/Release Branch myRelease set up to track remote branch Release from origin. Switched to a new branch 'myRelease' |
作用是checkout远程的Release分支,在本地起名为 myRelease分支,并切换到本地的myRelase分支。 |
git merge branch_xxxx |
合并分支 |
$: git checkout master $: git merge issue1234 Merge made by recursive. README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) |
如果,需要将dev分支合并到master上,则需要首先将当前的分支切换到master,合并后,别忘git push |
git branch new_branch_xxxx |
新建一个分支 |
|
如果newbranch名字分支已经存在,则需要使用-M强制重命名,否则,使用-m进行重命名。 |
git branch -m | -M oldbranch newbranch |
重命名分支 |
|
|
git branch -d | -D branchname
git branch -d -r remote_branchname |
删除本地、远程分支 |
|
|
git push origin local_new_branch |
本地新分支推送到远程 |
|
这里的含义是将local_new_branch这个分支提交到远程仓库上面。如果远程仓库没有这个分支,那么也会新建一个该分支。 |
git push origin local_new_branch:master |
指定提交到远程仓库的某个分支上 |
|
|
git pull origin local_new_branch:master |
把远程仓库的master与我的local_new_branch分支合并(merge) |
|
如果您使用“git pull master”,含义就是将远程仓库的master分支合并下来。如果本地没有master分支,那么本地就新建一个master分支 |
1.16 初始化一个新的工程
先在github之类的网站上新建一个工程,不添加任何文件。此时如果想要仅初始化一个dev分支。
可以在本地将该工程git clone下来;
燃后,新建一个readme.md, .gitignore文件
之后commit,push。在push时,若在idea下,填写push的分支为dev即可。
1.17 回退远程git
(1) soft方式回退到远程某次commit
(2) git push origin dev --force
1.18 Unresolved Conflicts
Can't commit changes due to unresolved conflicts.
Pulling is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
Exiting because of an unresolved conflict.
git status 查看状态,解决冲突
git add file
git commit -m "fix
conflict"
git push -f
https://blog.csdn.net/weixin_45785873/article/details/107096827
1.19 TAG 的删除
Github的Release,是建立在Git的tag上,是对tag的一层封装。Git的tag只是一个标签,而Github的Release在Tag的基础上,还可以包含更多的打包文件,比如可执行文件等。因此,在Github上,删除了Release后,这个Release对应的tag还存在,还要继续再删除一次,这个tag才会消失。
如何在本地删除Tag,并push到Github
git tag -d <tagname>
删除本地tag
git push origin --delete <tagname>
删除远端tag
git push origin <tagname>
向远端推送本地tag
git push origin --tags
向远端推送本地所有tag
https://www.maixj.net/ict/release-tag-22821
1.20 添加license
https://www.cnblogs.com/chenmingjun/p/8555906.html
1.21 删除远程仓库的文件而不删除本地文件
在删除成功后重新提交和push,即可更新远程仓库。
git rm -r --cached XXXX
git commit -m "XXXX"
git push -u origin master
注:
在删除远程仓库的文件时,务必重新clone一份,并在这份源码上操作,不能在最原始的源码上操作,容易丢失文件。
1.x 其他常用命令
强推
git push -f origin[远程仓库名称] dev[分支名称]
其它
git diff 显示暂存区和工作区的差异
git fetch origin 拉取对应的仓库, 合并到指定的分支(git merge origin/master
git remote add origin git@xxxx.git 在本地仓库中建立一个与远程仓库的别名,以便之后提交代码而不是每次都要输入远程仓库地址
二、SVN和Git的基本原理
理解git的思想,而不是单纯的会使用几个命令。知其然,更要知其所以然。
三、Git基本操作
3.1 常用命令
3.2 分支操作
常用命令
git branch列出所有本地分支
git branch -r列出所有远程分支
git branch -a列出所有本地分支和远程分支
git branch [branch-name]新建一个分支,但依然停留在当前分支
git checkout -b [branch-name]新建一个分支,并切换到该分支
git branch --track [branch] [remote-branch]新建一个分支,与指定的远程分支建立追踪关系
git checkout [branch-name]切换到指定分支,并更新工作区
git branch -d [branch-name]删除分支
git push origin --delete [branch-name]删除远程分支
3.3 merge操作
merge命令把不同的分支合并起来。如上图,在实际开放中,我们可能从master分支中切出一个分支,然后进行开发完成需求,中间经过R3,R4,R5的commit记录,最后开发完成需要合入master中,这便用到了merge。
git fetch [remote]merge之前先拉一下远程仓库最新代码git merge [branch] 合并指定分支到当前分支
一般在merge之后,会出现conflict,需要针对冲突情况,手动解除冲突。主要是因为两个用户修改了同一文件的同一块区域。如下图所示,需要手动解除。
当你在git分支中工作时,你最终必须将该代码与其他应用程序集成。学习如何使用git merge来实现这一点。
--------------------------------------------------------------------------------------------------
将功能分离到不同的分支对于任何严肃的开发人员来说都是至关重要的。通过分离每个功能,错误修复或正在运行的实验,您将避免很多问题并保持开发分支的清洁。
在某个时候,一段代码会达到你想要将它与项目其余部分整合的状态。这是git merge命令进来的地方。
准备合并
假设我们想要将分支修补程序合并 到您的主分支中。
在我们开始之前,您如何确保您已准备好合并您的更改?
检查您的本地存储库是否与来自远程服务器的最新更改保持一致git fetch。提取完成后,使用该 git checkout master命令。通过执行确保主分支具有最新的更新git pull。签出到应该接收更改的分支,在我们的情况下是主人。
合并
一旦准备工作完成后,你可以开始与合并 git merge hotfix的命令。
快进合并
一个快进合并时,有之间的线性路径可以发生分支,我们要合并。如果主服务器没有发生分离,而不是创建一个新的提交,它只会将主服务器指向修补程序分支的最新提交。所有来自修补程序分支的提交现在都可以在主分支中使用。
然而,如果分支机构已经分化,则快速合并是不可能的。在这种情况下,您想使用三路合并。
三路合并用额外的承诺来将两个分支联系在一起。
测试一下!使用RSpec测试分支创建您自己的项目,同时编辑master中的Controller测试。现在,尝试合并。
如何处理合并冲突
一个合并冲突,当你试图合并这两个两个分支改变了同一个文件的同一部分出现。发生这种情况时,Git将无法确定要使用哪个版本。
例如,如果该文件example.rb在同一Git存储库的不同分支中的相同行上进行了编辑,或者该文件已被删除,则当您尝试合并这些分支时,您将收到合并冲突错误。在继续之前,合并冲突必须通过新提交来解决。
合并冲突只会发生在三方合并的情况下。
1.生成 需要解析的文件列表: git status
# On branch master
# You have unmerged paths.
# (fix conflicts and run "git commit")
# Unmerged paths:# (use "git add ..." to mark resolution)
# both modified: example.rb
# no changes added to commit (use "git add" and/or "git commit
-a")
2.当 遇到冲突线时,Git将使用 标记冲突内容两侧的可视指示符编辑受影响文件 的内容。这些可视标记是:
<<<<<<<- 冲突标记,冲突开始于此行之后。=======- 将您的更改与另一个分支中的更改分开。>>>>>>>- 冲突线的结束。
<<<<<<< HEAD(master)
conflicted text from HEAD(master)
=======
conflicted text from hotfix
>>>>>>> hotfix
决定是否仅保留修补程序或主修改,或者写一个全新的代码。在合并您的更改之前删除冲突标记。
当你准备合并时,你所要做的就是在冲突的文件上运行这个 git add命令来告诉他们已经解决了。
提交您的更改git commit以生成合并提交。希望这有助于您更好地了解如何合并分支机构并处理冲突。
3.4 rebase操作
rebase又称为衍合,是合并的另外一种选择。
在开始阶段,我们处于new分支上,执行git rebase dev,那么new分支上新的commit都在master分支上重演一遍,最后checkout切换回到new分支。这一点与merge是一样的,合并前后所处的分支并没有改变。head依然指向new分支
git rebase dev,通俗的解释就是new分支想站在dev的肩膀上继续下去。rebase也需要手动解决冲突。
rebase与merge的区别
现在我们有这样的两个分支,test和master,提交如下:
D---E test /A---B---C---F master在master执行git merge test,然后会得到如下结果:
D--------E / A---B---C---F----G test, master在master执行git rebase test,然后得到如下结果:
A---B---D---E---C'---F' test, master可以看到,merge操作会生成一个新的节点,之前的提交分开显示。而rebase操作不会生成新的节点,是将两个分支融合成一个线性的提交。
如果你想要一个干净的,没有merge commit的线性历史树,那么你应该选择git rebase。如果你想保留完整的历史记录,并且想要避免重写commit history的风险,你应该选择使用git merge。
3.5 reset
reset命令把当前分支指向另一个位置,并且相应的变动工作区和暂存区。这个命令还是比较危险的。操作时请确保你知道你要做什么。
git reset —soft [commit]只改变提交点,暂存区和工作目录的内容都不改变git reset —mixed [commit]改变提交点,同时改变暂存区的内容git reset —hard [commit]暂存区、工作区的内容都会被修改到与提交点完全一致的状态git reset --hard HEAD让工作区回到上次提交时的状态,本地的修改都不要了。
3.6 revert
git revert用一个新提交来消除一个历史提交所做的任何修改。如上图,将提交回滚到15df9b6。
revert与reset的区别
git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,减少冲突。但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入,产生很多冲突。git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。分支策略
master主分支应该非常稳定,用来发布新版本,一般情况下不允许在上面工作,工作一般情况下在新建的dev分支上工作,工作完后,比如上要发布,或者说dev分支代码稳定后可以合并到主分支master上来。
push
上传本地仓库分支到远程仓库分支,实现同步。
git push [remote] [branch]上传本地指定分支到远程仓库git push [remote] --force强行推送当前分支到远程仓库,即使有冲突。不建议使用git push [remote] --all推送所有分支到远程仓库
打标签操作
Git 支持两种标签:轻量标签(lightweight)与附注标签(annotated)。
git tag v1.0 //轻量标签git tag -a tagName -m "my tag" //附注标签。建议使用后期打标签
假如你忘记了对某个提交打标签,可以后期补上
git tag -a v1.2 9fceb02 -m "补打标签"
将tag同步到远端仓库
默认情况下,git push 命令并不会传送标签到远程仓库服务器上。在创建完标签后你必须显式地推送标签 使用git push origin [tagName]推送单个分支。
git push origin v1.0推送本地所有tag,使用git push origin --tags。
3.7 切换到某个tag
跟分支一样,可以直接切换到某个tag去。
git checkout v1.0但是注意:这个时候不位于任何分支,处于游离状态,可以考虑基于这个tag创建一个分支。
git checkout -b 新分支名 v1.0
3.8 其他命令
git status显示有变更的文件git log显示当前分支的版本历史git diff显示暂存区和工作区的差异git diff HEAD显示工作区与当前分支最新commit之间的差异git cherry-pick [commit]选择一个commit,合并进当前分支
3.9 Git问题解决
员工密码定期修改后的问题
我们的git仓库bitbucket密码是和员工账号密码绑定的。我们的员工密码每两个月会强制修改一次,导致git密码校验失败。
错误显示:remote error: CAPTCHA required
解决:
1,打开控制面板;
2.点击打开用户账户;
3.点击打开凭证管理(windows凭证管理栏)
4.普通凭证下拉打开修改你已存在的git账号密码
修改或删除都可以
回到浏览器上把账户退出,重新登录下这一步经常会漏。
放弃本地修改
本地代码被改乱了。想要放弃重来。分三种情况。
1. 未使用git add 缓存代码
放弃某个文件的修改注意中间有--git checkout -- filename放弃所有文件修改 git checkout .git checkout .此命令用来放弃掉所有还没有加入到缓存区(就是 git add 命令)的修改:内容修改与整个文件删除注意:此命令不会删除新建的文件,因为新建的文件还没加入git管理系统中,所以对git来说是未知,只需手动删除即可2. 已使用git add 缓存代码,未使用git commit
使用 git reset HEAD filenamegit reset HEAD filename放弃所有文件修改 git reset HEADgit reset HEAD此命令用来清除 git 对于文件修改的缓存。相当于撤销 git add 命令所做的工作。在使用本命令后,本地的修改并不会消失,而是回到了第一步1. 未使用git add 缓存代码,继续使用用git checkout -- filename,就可以放弃本地修改
3. 已经用 git commit 提交了代码
使用 git reset --hard HEAD^ 来回退到上一次commit的状态git reset --hard HEAD^或者回退到任意版本git reset --hard commit id ,使用git log命令查看git提交历史和commit idgit reset --hard commit id
Git中文件标题颜色变化的含义
绿色,已经加入控制暂未提交
红色,未加入版本控制
蓝色,加入,已提交,有改动
白色,加入,已提交,无改动
灰色:版本控制已忽略文件。
REF:
Git最全总结(全篇),20.3.17
git 从远程服务器更新本地项目,19.5
一个关于Git合并的教程,18.5
Git撤销已经commit但是还没有push的代码,18.10
git删除远程文件夹或文件的方法, 18.12
【git】git add 添加错文件 撤销, 18.1
Git撤销对远程仓库的push&commit提交, 18.9
git命令之git merge 和 git rebase的区别,福喜900,
18.2
git stash详解,18.6
从一个git仓库迁移代码到另一个git仓库(亲测有效版), 18.6
git 下载项目(zip)后,关联远程仓库以及所出现的问题(error: 无法推送一些引用到), 20.3
How to clone git repository from its zip, 20.1
用git,clone依赖的库,19.4
主git仓库添加依赖第三方git仓库, 19.6
git 切换远程仓库地址,19.1
Git使fork项目与源项目保持一致方法, 15.7
Git使用---fork项目(windows), 18.4
git fatal: 拒绝合并无关的历史的错误解决, 18.1
github fork 别人的项目源作者更新后如何同步更新, 18.5
3.3 Git 分支 - 分支管理,20.5
Git branch使用, 19.5
git branch用法总结,
16.9
idea中安装git后,代码颜色代表的含义,
19.11
Github删除远程仓库的文件而不删除本地文件, 20.7