git 使用学习总结和问题汇总

push代码时,冲突情况

情况说明

我们看看下面的提交记录
在这里插入图片描述
可以看到有一次merge的记录,这是怎么造成的呢?
其实这种结果在我们开发中很常见,A开发者在本地提交了代码,commit id是d2bf0ca1,然后push到远端,B开发也在本地提交了代码,commit id是29f52e29,push的时候失败了,因为远端有新提交了;这时,我们会使用git pull,拉取远端最新提交到本地,这时就会生成a5e16740的merge记录。这种操作会导致不必要的merge 提交记录。
我们怎么避免呢?

  • 我们在本地提交的时候,先进行pull,pull因为冲突失败的话,先把本地修改stash藏匿起来,等pull成功,git stash pop把代码还原回来。
  • 本地已经commit了,可以在pull的时候用–rebase,这样也能保证提交记录是一条直线

参考

git rebase 学习

分支merge

merge分支很简单,如果没有冲突会生成一条merge commit记录,关键的遇到冲突的时候,这个就需要手动解决了。
对同一个文件的同一行代码,多条commit都修改时,就会冲突
在这里插入图片描述
上图发生了冲突,我们手动解决冲突,把需要的保留,不需要的删除了。
上面的冲突比较简单,很好处理。

有些文件的冲突很多,因为git是按照行比较的,一个大文件冲突的时,大面积代码是错乱的,或者有些删除的代码又回来,解决冲突很麻烦,需要认真比对。git的冲突提示只是提示我们有冲突的,有时只根据冲突标记很难解决冲突,需要我们根据业务逻辑自行分析解决。冲突解决完以后,最后通过工具(mac自带的FileMerge)比对一下文件最终是不是我们想要的。

还有二进制的jar,git合并就无能为力了,需要我们自行替换成正确的jar包。

记录一次痛苦的merge

两个分支A和B差了5个月,A分支是平时开发的分支,B分支单独做一个大功能。
现在要进行合并了,注意,我们要把B和到A上,千万别反过来,因为A是团队都在开发的分支,历时五个月更新代码量巨大。
我把B merge到A上,解决完冲突,build失败

e: java.lang.IllegalStateException: failed to analyze: com.sun.tools.javac.util.ClientCodeException: java.lang.IllegalStateException: node.sym must not be null
	at org.jetbrains.kotlin.analyzer.AnalysisResult.throwIfError(AnalysisResult.kt:56)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:182)
	...
Caused by: com.sun.tools.javac.util.ClientCodeException: java.lang.IllegalStateException: node.sym must not be null
	at com.sun.tools.javac.api.ClientCodeWrapper$WrappedTaskListener.finished(ClientCodeWrapper.java:685)
	at com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:111)
	...
Caused by: java.lang.IllegalStateException: node.sym must not be null
	at org.jetbrains.kotlin.kapt3.base.incremental.TypeTreeVisitor.visitIdentifier(javacVisitors.kt:133)
	at org.jetbrains.kotlin.kapt3.base.incremental.TypeTreeVisitor.visitIdentifier(javacVisitors.kt:50)
	...

靠,看这个报错,很难知道是怎么回事,google后发现是因为kotlin和java同名文件导致的。
为啥会有kotlin和java的同名文件呢?
分析发现是因为当时,创建B分支的时候,代码还都是java代码,后来A项目中的代码整体都改成了koltin代码,在B项目中又对文件进行了修改,在merge的时候,git会认为这是两个文件,自动合并不了,所以两个文件都存在了,这时就需要我们手动合并了。代码修改不对的还好,修改很多的时候,而且,同一个文件B中java版本也修改过,A中kotlin版本也修改过,这个手动合并真是痛苦。
我们手动合并完后,把同名的java文件删了。

merge遇到的一个问题

把A分支的代码merge到B分支后,有冲突,解决冲突后准备提交了,发现B分支别人有新的提交,自己把解决冲突还没commit的代码stash了,把B分支pull到最新,然后再stash pop,结果发现merge的提交记录都没有了。。。。虽然最终的代码是对的,但是后续想找提交记录就很麻烦。

以后千万别这么干,解决冲突后得先commit

参考

Android Studio Kotlin Complier Error node.sym must not be null

Android studio 中patch的使用

AS是可以通过可视化的方式帮助我们和方便的生成patch文件的,既可以针对local changes也可以针对commit。
在这里插入图片描述
这样就生成了一个patch文件,使用的时候,直接拖入AS中就能自动识别

当然,使用git命令行也是可以实现的

参考

Android Studio生成patch和使用patch
如何使用git 生成patch 和打入patch
如何用git命令生成Patch和打Patch

Git分支间同步未提交的修改

Git分支间同步未提交的修改

git stash的使用

git stash 用法总结和注意点

git基于tag创建分支

自己操作坑了自己

自己需要把developer的代码merge到developer_lzy分支上
我先developer pull代码
developer merge 到developer_lzy上,有冲突,解决了冲突,然后stash
然后我又切到developer上pull代码,切回到developer_lzy上,从developer上merge代码
冲突了,我执行了checkout .把代码都删了,然后我stash pop,我执行commit、push

我靠,我这一系列奇葩操作。。。
最终导致developer_lzy 有第二次merge的提交记录,到底没有相应的代码改动
最大的失误在于最后的push,要是只是本地commit还好。

最后的解决办法是,我本地developer_lzy回滚到第一次merge前的提交上。强制把我们本地的分支提交到远端,这种操作很危险。我又重头merge来一遍才解决的。
Git push的常见用法

git checkout 使用

git checkout 命令图文详解

git cherry pick使用

git cherry-pick 多个commit操作