git版本合并|关于git怎样合并不同版本

|

1. git到底怎么合并,有冲突都要手动吗

冲突的产生很多命令都可能出现冲突,但从根本上来讲,都是merge 和 patch(应用补丁)时产生冲突。而rebase就是重新设置基准,然后应用补丁的过程,所以也会冲突。git pull会自动merge,repo sync会自动rebase,所以git pull和repo sync也会产生冲突。当然git rebase就更不用说了。冲突的类型逻辑冲突git自动处理(合并/应用补丁)成功,但是逻辑上是有问题的。比如另外一个人修改了文件名,但我还使用老的文件名,这种情况下自动处理是能成功的,但实际上是有问题的。又比如,函数返回值含义变化,但我还使用老的含义,这种情况自动处理成功,但可能隐藏着重大BUG。这种问题,主要通过自动化测试来保障。所以最好是能够写出比较完备的自动化测试用例。这种冲突的解决,就是做一次BUG修正。不是真正解决git报告的冲突。内容冲突两个用户修改了同一个文件的同一块区域,git会报告内容冲突。我们常见的都是这种,后面的解决办法也主要针对这种冲突。树冲突文件名修改造成的冲突,称为树冲突。比如,a用户把文件改名为a.c,b用户把同一个文件改名为b.c,那么b将这两个commit合并时,会产生冲突。$ git status added by us: b.c both deleted: origin-name.c added by them: a.c如果最终确定用b.c,那么解决办法如下:git rm a.cgit rm origin-name.cgit add b.cgit commit执行前面两个git rm时,会告警“file-name : needs merge”,可以不必理会。 树冲突也可以用git mergetool来解决,但整个解决过程是在交互式问答中完成的,用d 删除不要的文件,用c保留需要的文件。最后执行git commit提交即可。内容冲突的解决办法发现冲突一般来讲,出现冲突时都会有“CONFLICT”字样:$ git pullAuto-merging test.txtCONFLICT (content): Merge conflict in test.txtAutomatic merge failed; fix conflicts and then commit the result. 但是,也有例外,repo sync的报错,可能并不是直接提示冲突,而是下面这样:error: project mini/sample注:无论是否存在冲突,只要本地修改不是基于服务器最新的,它都可能报告这个错误,解决方法都是一样。 这个时候,需要进入报错的项目(git库)目录,然后执行git rebase解决:git rebase remote-branch-name冲突解决的一般过程merge/patch的冲突解决先编辑冲突,然后git commit提交。注:对于git来讲,编辑冲突跟平时的修改代码没什么差异。修改完成后,都是要把修改添加到缓存,然后commit。rebase的冲突解决rebase的冲突解决过程,就是解决每个应用补丁冲突的过程。解决完一个补丁应用的冲突后,执行下面命令标记冲突已解决(也就是把修改内容加入缓存):git add -u注:-u 表示把所有已track的文件的新的修改加入缓存,但不加入新的文件。 然后执行下面命令继续rebase:git rebase –continue有冲突继续解决,重复这这些步骤,直到rebase完成。 如果中间遇到某个补丁不需要应用,可以用下面命令忽略:git rebase –skip 如果想回到rebase执行之前的状态,可以执行:git rebase –abort 注:rebase之后,不需要执行commit,也不存在新的修改需要提交,都是git自动完成。编辑冲突的方法直接编辑冲突文件冲突产生后,文件系统中冲突了的文件(这里是test.txt)里面的内容会显示为类似下面这样:a123<<<<<<< HEADb789=======b45678910>>>>>>> c其中:冲突标记<<<<<<< (7个<)与=======之间的内容是我的修改,=======与>>>>>>>之间的内容是别人的修改。此时,还没有任何其它垃圾文件产生。 最简单的编辑冲突的办法,就是直接编辑冲突了的文件(test.txt),把冲突标记删掉,把冲突解决正确。

2. git怎么把主分支代码合并到我的分支

1.git checkout xxx(切换到你要将其他分支合并到的主分支上,xxx是分支名) 2.git merge xxx (合并操作) 3.git branch -d xxx(删除已经合并的分支,可选择不删除) git clone url #克隆新的版本库 02 git init 03 git pull repo_name #有关联的

3. IDEA如何整合Git

最近公司使用Git进行协作,有时候,开发团队可能需要多个人开发同一个模块,甚至修改同一个文件,在使用Git的过程中有一些细节需要大家注意。

一般步骤

1. 拉取远端源时先提交本地代码

注意:如果不提交本地程序,直接合并远端源会导致本地修改的文件丢失。额外:如果不想提交本地代码,可以使用Git stash命令。

个人建议先提交程序。不要使用git stash暂存起来。

2. 本地提交记录与远端源合并,并解决冲突。

如果两个人修改了同一个文件,会产生冲突。冲突的格式Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,冲突的内容。如下

冲突的格式

3.解决冲突的时候,代表又修改了冲突的文件,我们需要重新提交。(commit)。

4.上传解决的冲突到远端服务器。

5、其他人拉取你修改的内容,进行合并。远端冲突的文件已经被解决,这时候可接受远端的文件。无需再次解决冲突。

额外

idea内置了版本控制,有很多好用的功能

2.1 生成ignore模板

需要安装ignore插件,在.gitignore文件下,右键,点击

添加gitignore内容

然后选择想要生成的ignore模板, 可以选择jetbrains,node,java等等。

Idea的git合并

idea为我们提供了很方便的操作,所以重点写一下。

3.1 右键某提交的信息

image.png

3.2 如果产生了冲突,会弹出合并窗口。

冲突窗口

3.3 合并冲突时候的策略与步骤。

1、点击Merge2、弹出如下对话框,这个时候我们可以选择只要本地的文件,或者只保留远端源的文件。中间部分为解决冲突的区域。

解决冲突的窗口

本地文件与远端文件都有一个小的标志,如何解决。点击之后中间的文件会变化,也就是我们如何解决冲突的文件。

image.png

合并完之后,点击Apply,文件就变成了我们刚才冲突窗口中的中间文件。

最后

Idea为我们提供了很多方便的操作,团队协作是作为开发人员一定要掌握的技能。重点在第三部分,希望能对大家有帮助。

1人点赞

Develop Tools

4. git合并不删除文件

直接点击合并。git合并文件并不是删除文件,而是生成了一个新的文件,可以直接点击合并文件即可,合并前的文件也会存在。

5. git分支合并为什么会发生冲突

在解决git merge的冲突时,有时我总忍不住吐槽git实在太不智能了,明明仅仅是往代码里面插入几行,没想到合并就失败了,只能手工去一个个确认。真不知道git的合并冲突是怎么判定的。在一次解决了涉及几十个文件的合并冲突后(整整花了我一个晚上和一个早上的时间!),我终于下定决心,去看一下git merge代码里面冲突判定的具体实现。正所谓冤有头债有主,至少下次遇到同样的问题时就可以知道自己栽在谁的手里了。于是就有了这样一篇文章,讲讲git merge内部的冲突判定机制。recursive three-way merge和ancestorgit的源码先用merge作关键字搜索,看看涉及的相关代码。找了一段时间,找到了git merge的时候,比较待合并文件的函数入口:ll_merge。另外还有一份文档,它也指出ll_merge正是合并实现的入口。从函数签名可以看到,mmfile_t应该就代表了待合并的文件。有趣的是,这里待合并的文件并不是两份,而是三份。int ll_merge(mmbuffer_t *result_buf,const char *path,mmfile_t *ancestor, const char *ancestor_label,mmfile_t *ours, const char *our_label,mmfile_t *theirs, const char *their_label,const struct ll_merge_options *opts)看过git help merge的读者应该知道,ours表示当前分支,theirs表示待合并分支。看得出来,这个函数就是把某个文件在不同分支上的版本合并在一起。那么ancestor又是位于哪个分支呢?倒过来从调用方开始阅读代码,可以看出大体的流程是这样的,git merge会找出三个commit,然后对每个待合并的文件调用ll_merge,生成最终的合并结果。按注释的说法,ancestor是后面两个commit(ours和theirs)的公共祖先(ancestor)。另外前面提到的文档也说明,git合并的时候使用的是recursive three-way merge。关于recursive three-way merge, wikipedia上有个相关的介绍#Recursive_three-way_merge)。就是在合并的时候,将ours,theirs和ancestor三个版本的文件进行比较,获取ours和ancestor的diff,以及theirs和ancestor的diff,这样做能够发现两个不同的分支到底做了哪些改动。毕竟后面git需要判定冲突的内容,如果没有原初版本的信息,只是简单地比较两个文件,是做不到的。鉴于我的目标是发掘git判定冲突的机制,所以没有去看git里面查找ancestor的实现。不过只需肉眼在图形化界面里瞅上一眼,就可以找到ancestor commit。(比如在gitlab的network界面中,回溯两个分支的commit线,一直到岔路口)有一点需要注意的是,revert一个commit不会改变它的ancestor。所谓的revert,只是在当前commit的上面添加了新的undo commit,并没有改变“岔路口”的位置。不要想当然地认为,revert之后ancestor就变成上一个commit的ancestor了。尤其是在revert merge commit的时候,总是容易忘掉这个事实。假如你revert了一个merge commit,在重新merge的时候,git所参照的ancestor将不是merge之前的ancestor,而是revert之后的ancestor。于是就掉到坑里去了。建议所有读者都看一下git官方对于revert merge commit潜在后果的说法: 结论是,如果一个merge commit引入的bug容易修复,请不要轻易revert一个merge commit。剖析xdiff从ll_merge往下追,可以看到后面出了一条旁路:ll_binary_merge。这个函数专门处理bin类型文件的合并。它的实现简单粗暴,如果你没有指定合并策略(theris或ours),直接报Cannot merge binary files错误。看来在git看来,二进制文件并没有diff的价值。主路径从ll_xdl_merge到xdl_merge,进到一个叫xdiff的库中。终于找到git merge的具体实现了。平心而论,xdiff的代码风格十分糟糕,不仅注释太少,而且结构体成员变量居然使用类似i1、i2这样的命名,看得我头昏脑胀、心烦意燥。吐槽结束,先讲下xdl_merge的流程。xdl_merge做了下面四件事:由xdl_do_diff完成two-way diff(ours和ancestor,theirs和ancestor),生成修改记录,存储到xdfenv_t中。xdl_change_compact压缩相邻的修改记录,再用xdl_build_script建立xdchange_t链表,记录双方修改。xdchange_t主要包括了修改的起始行号和修改范围。这时候分三种情况,其中两种是只有一方有修改(只有ours或theirs一条链表),直接退出。最后一种是双方都有修改,需要合并修改记录。由于修改记录是按行号有序排列的,所以直接合并两个链表。修改记录如果没有重叠部分,按先后顺序标记为我方修改/他方修改。如果发生了重叠,就表示发生了冲突。之后会重新过一遍两个待合并链表,对于那些标记为冲突的部分,比较它们是否相等的,如果是,标记为双方修改。由xdl_fill_merge_buffer输出合并结果。如果有冲突,调用fill_conflict_hunk输出冲突情况。如果没有冲突(标记为我方修改/他方修改/双方修改),则合并ancestor的原内容和修改记录,按标记的类型取修改后的内容,并输出。输出冲突情况的代码位于fill_conflict_hunk中。它的实现很简单,毕竟此时我们已经有了双方修改的内容,现在只需要同时输出冲突内容,供用户取舍。(这便是那次花了一个晚上和一个早上改掉的冲突的源头,凶手就是你,哼)。输出格式恐怕大家都很熟悉。该函数会先打印若干个。这个就是折磨人的合并冲突了:<<<<<<< HEAD3=======2>>>>>>> branch1总结git merge的冲突判定机制如下:先寻找两个commit的公共祖先,比较同一个文件分别在ours和theirs下对于公共祖先的差异,然后合并这两组差异。如果双方同时修改了一处地方且修改内容不同,就判定为合并冲突,依次输出双方修改的内容。

6. 怎样设置git默认合并工具

首先安装好WinMerge,这一步没什么好说的,就是点击下一步就好。记得要点那个把WinMerge添加到环境变量里的选项,如果没选的话下一步需要修改profile文件。然后配置Git Bash的PATH变量,之前很多教程都在说这个PATH但是都不甚详细。我摸索了一下(怪我自己Linux知识不熟),直接上代码大家应该能看明白。export PATH="$PATH:/c/Program Files/WinMerge/"。不过还有一个问题就是上面那句命令只能在不关闭bash前生效,可以去../Git/etc/里面修改profile文件,在最后一行加上上面那行命令就行。第三步需要下载其他文件,由于我的Git版本是2.4.5,mergetool里面并没有添加对winmerge的支持,但是自从2.5.0之后Git添加了对winmerge的支持,所以我就从Git在github的主页上下载了最新的源码,从源码的/mergetool/目录下面了一份winmerge文件到../Git/mingw32/libexec/git-core/mergetool/下面。如果是Git2.x一下的版本目录应该是../Git/libexec/git-core/mergetool/。完成这三步之后就可以尝试一下了,在bash里面输入git mergetool –tool-help。这时候bash就会列出能够使用的工具,如果winmerge在可用的那一栏里,就标志着可以用了。这时候还得让git知道你要用winmerge了。还需要在bash里面输入以下命令:git config –global merge.tool winmerge。

7. git如何合并两个分支代码

加入有两个分支,分别为:branch1,main,需要将branch1合并到main:切换到main分支,合并branch1分支git checkout maingit merge branch1

8. git 合并分支是什么意思

eclipsegit合并分支步骤如下:

1、开始进行分支合并操作,先切换回主干(注意此时的主干是我们创建分支时候的主干,不是现在主干进行的情况),如下图所示:

3、这个时候通常情况下是没有错误的,接下来要进行一步操作,很危险,就是将最新版本的master给pull下来;修改完冲突之后,进行提交,并推送到主干即可;4、完成提交之后,我们可以将我们的分支删除。登陆eclipse到其他地方选择一次clone,检查是否完成合并。

9. 关于git怎样合并不同版本

举个例子:git rev-list –after="Fri Jan 6 11:47:13 2017 +0800" –before="Fri Jan 11 11:47:13 2017 +0800" –reverse master | git cherry-pick –stdin先用git rev-list把一段时间内的变更列出来,然后用管道传给git cherry-pick。注意到回是为了cherry-pick,所以rev-list的输出顺序反一答下,变成最老的先输出。


赞 (0)