git conflict

git conflict 是日常协作中必不可少的。

在gitlab的web页面上,有三种处理conflict的视图,其中line的文本方式最灵活。

这种方式中:

其中<<<<<<< HEAD 到 ======= 中间的内容是local提交的。

======= 到 >>>>>>> commit-id 是远程仓库中的内容。

示例:

<<<<<<< HEAD

新提交的代码xxx

=======

远程仓库的代码xxx

>>>>>>> commit-id 

svn迁移到git,并保持提交记录

svn迁移git是一个很常见的需求。

大部分人希望保留详细的提交记录,因为提交记录是代码版本管理的核心价值。

步骤

  1. 导出用户(非必要)
    svn log 远程SVN仓库地址 -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2"="$2" <"$2"@xxx.com>"}' | sort -u > ./users.txt
    执行完后手动修改对应的新用户映射关系,如果没有对应的都可以设置成同一个
  2. git svn clone 远程SVN仓库地址 --no-metadata --authors-file=users.txt GitProject, gitproject 是一个空的目录,表示git项目名称。
  3. 添加必要的.gitignore文件
  4. cd GitProject
  5. git remote -v,如果不为空,则删除原有origin:git remote rm origin
  6. 增加远程仓库的地址:git remote add origin git@x.x.x.x/project-name.git
  7. push到远程仓库,必要的话,强制push
    git push -u -f origin master

常见问题FAQ

  • 在clone中断时,我们尝试再次执行clone命令,提示了如下的内容:Using existing [svn-remote "svn"] svn-remote.svn.fetch already set to track :refs/remotes/git-svn
    解决:进入git目录,执行 git svn fetch,继续代码的clone行为。

  • 如果提示不支持 git svn,请安装 git-svn

  • 在执行的过程中提示APR does not understand this error code: ra_serf: An error occurred during decompression at /usr/share/perl5/Git/SVN/Ra.pm
    这个问题比较棘手,前后尝试了将近2天,刚开始以为仓库代码太大,几十G,大文件不稳定导致,所以尝试了好多次,后面google了下,感觉跟版本有关,又受限于服务器配置不能改,有点无奈。后面在windows中尝试,系统莫名重启,继续在ubuntu20中,才成功。
    出问题的环境版本
    ubuntu:14.04.3
    git: git version 1.9.1
    OK的环境
    ubuntu:ubuntu1~20.04
    Git:git version 2.25.1

解除gitlab仓库的保护

问题

在git push时,错误提示如下:

remote: GitLab: You are not allowed to force push code to a protected branch on this project.To git@xxx:xxx.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: 无法推送一些引用到 'git@xxx:xxx.git'

关键内容就是protected branch,所以我们需要确认是怎么protected。

解决

repo->settings->repository->protected branches:
file

git personal token issue

remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.

fix:

git remote set-url origin  https://tokenj@github.com/username/reponame.git/

如何在push前修改或者删除commit注释

方法1:

git reset --soft HEAD^

这样就成功撤销了commit,如果想要连着add也撤销的话,–soft改为–hard(删除工作空间的改动代码)。

命令详解:

HEAD^ 表示上一个版本,即上一次的commit,也可以写成HEAD~1
如果进行两次的commit,想要都撤回,可以使用HEAD~2

–soft
不删除工作空间的改动代码 ,撤销commit,不撤销git add file

–hard
删除工作空间的改动代码,撤销commit且撤销add

方法2:

git commit --amend

进入vim后,正常编辑后wq退出

This branch has conflicts that must be resolved 解决示例

使用git日常免不了遇到conflicts,那么如何消除conflicts呢,以下的内容以一个具体的过程来讲解整个过程和原理。

以下我们手动创造一个conflicts:
git conflicts

Step 1: From your project repository, check out a new branch and test the changes.

git checkout -b apache-master master
git pull https://github.com/apache/incubator-apisix.git master

Step 2: Merge the changes and update on GitHub.

git checkout master
git merge --no-ff apache-master
git push origin master

以上的的例子, 我们从A合入到B:B <== A。
A: https://github.com/apache/incubator-apisix.git
B: xxxx/incubator-apisix.git

例子中有一个README.md的冲突,并且给出了解决的命令行参考。
我们将逐条命令来解释如何按照提示解决冲突。

  1. 假设我们已经在B的git 根目录下。
  2. git checkout -b apache-master master #建立B的 apache-master分支,并切换到apache-master
  3. git pull https://github.com/apache/incubator-apisix.git master # 将A最新的内容合入apache-master
  4. 因为有冲突,所以上条执行时,会提示冲突:
From https://github.com/apache/incubator-apisix
 * branch            master     -> FETCH_HEAD
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
  1. 解决冲突[ ... resolve any conflicts ... ]:
    手动打开冲突文件,根据提示修改,删除冲突的内容,留下想要的结果内容。
  2. git add [files that were conflicted]
  3. git commit,将冲突修改提交敖本地仓库:
$ git commit -m "resolve the conflict"
[apache-master 6ad2d5e] resolve the conflict
  1. git checkout master # 将B切换为master
  2. git merge --no-ff apache-master #将B仓库的apache-master 合入 master
  3. git push origin master #将B仓库的最终的本地库推到云端master

最终解决了冲突,完成了对B master的更新。

希望以上就解释清楚,谢谢!

通过源码将git升级到最新版

因为go-get下载hugo失败,需要升级git到最新版本。

下载最新git代码

wget -O git-master.zip https://github.com/git/git/archive/master.zip

编译

unzip git-master.zip
cd git-master

yum install openssl-devel curl-devel expat-devel perl-ExtUtils-MakeMaker gettext gettext-libs gettext-devel asciidoc xmlto docbook2X

ln -s /usr/bin/db2x_docbook2texi /usr/bin/docbook2x-texi

错误

libgit.a(utf8.o): In function `reencode_string_iconv':
/usr/local/git/utf8.c:463: undefined reference to `libiconv'
libgit.a(utf8.o): In function `reencode_string_len':
/usr/local/git/utf8.c:502: undefined reference to `libiconv_open'
/usr/local/git/utf8.c:521: undefined reference to `libiconv_close'
/usr/local/git/utf8.c:515: undefined reference to `libiconv_open'
collect2: ld returned 1 exit status
make: *** [git-credential-store] Error 1

从错误提示看,是缺少libiconv。

安装libiconv

  1. 下载编译

    cd /usr/local
    wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
    tar -zxvf libiconv-1.14.tar.gz
    cd libiconv-1.14
    ./configure –prefix=/usr/local/libiconv && make && make install

  2. 创建一个软链接到/usr/lib

    ln -s /usr/local/lib/libiconv.so /usr/lib
    ln -s /usr/local/lib/libiconv.so.2 /usr/lib

  3. 然后回到git目录继续编译

    cd /usr/local/git
    make configure
    ./configure --prefix=/usr/local --with-iconv=/usr/local/libiconv
    make
    make install

  4. 此时,git应该编译安装成功了,测试如下:

    $ git --version
    git version 2.5.0