乐蛙小院 - GIT
type: channel
link: https://blog.keer.me/category/git/
description: 先进的版本控制系统
items: git cherry-pick合并某个commit
items: 使用Gogs配置git-hook部署代码
items: 如何避免git pull时产生'Merge branch 'master' of...等类似操作
items: Git从入门到精通[更新中...]
items: Linux简易安装Git服务器
items: Git Pull 避免用户名和密码方法

git cherry-pick合并某个commit
type: item
date: 2020-05-11T11:04:00+08:00
description: 在一般的项目开发过程中，我们一般在开发分支(develop)上提交，等项目开发完成后我们在使用merge命令合并到主分支(master)上。但是可能会出现这样的一种情况在develop的开发过程中项目希望提前使用到develop分支上的一个新功能，而不想把develop还没开发完成的其他功能一起提交上线，那么这样的情况我们就需要使用到cherry-pick命令了。简述cherry-pick这个命令和merge很类似，但是cherry-pick操作的对象是commit，就是对已经存在的commit 进行再次提交。使用方式也很简单：git cherry-pick <commit id>commitid我们可以使用git log命令来查看到。实践简单介绍一下提交流程：首先我们切换到develop分支上，然后我们新增3个提交git checkout develop git commit -m "add 内存配置" git commit -m "add 硬盘配置" git commit -m "add 显卡配置"提交日志如下接着我们切换到master分支上，再次查询下日志我们现在要做的就是把add内存配置(0321b70)和add 硬盘配置(0f16d73)合并到master分支上，多余的那个add 显卡配置(1e1aa1f)我们模拟开发尚未完成的功能，先不合并。{ maxrnb } master » git cherry-pick 0321b70 0f16d73 [master 9ae7418] add 内存配置 Date: Mon May 11 10:00:29 2020 +0800 1 file changed, 2 insertions(+), 1 deletion(-) [master fbdfe5d] add 硬盘配置 Date: Mon May 11 10:01:04 2020 +0800 1 file changed, 2 insertions(+), 1 deletion(-) { maxrnb } master » 可以看到使用cherry-pick的合并是在master分支上新生成了一个commit，对应的commitid分别为9ae7418、fbdfe5d，并不是我们平常使用的Fast-forward合并模式。我们从log里也可以很清楚的看到扩展刚刚是一个或者两个提交cherry-pick到master分支，但如果有100个commit要合并到master分支呢？总不能这样一个个操作吧？cherry-pick还提供了一个方便合并区间的方式。git cherry-pick commit1..commit100但是要注意，这是一个左开右闭的操作，也就是说，commit1不会被合并到master分支，而commit100则会。刚刚上面也说了，cherry-pick每拣选一个commit就会提交一次生成一个新的commit。 如果我们想让每个commit 拣选后暂缓提交，等到所有commit都拣选完成后，自己手动commit，应该怎么办呢？可以采用-n选项来操作。这个时候，我们查看log的话发现log图谱中并没有出现新的commit，所以我们继续合并，最后手动执行git commit -m "合并 添加内存、添加硬盘提交"最后，log图谱如下。可以很清楚看到虽然我们抽取了2次commit来合并，但是最终在master上只产生了一个新的commit，对应着图谱中的f24a43f。问题有的人(比如我)可能会有这样的操作，cherry-pick后面跟一系列commitid最后的一个。按照上面的列子我执行git cherry-pick 0f16d73会怎么样？冲突内容如下<<<<<<< HEAD CPU: i5-7200U ======= CPU: i5-7200U Merory: 芝奇16G x 2 DIsk: 三星970Evo Pro >>>>>>> 0f16d73... add 硬盘配置这样操作的话会出现冲突，但是同样可以通过和解决普通冲突一样来操作。不过还是建议通过cherry-pick后面跟一个或多个commitid来操作规范。总结cherry-pick这个命令我个人平时工作中使用到的情况还是比较少的，使用的更多的依然是merge。但是这cherry-pick有更高的灵活性及更强大的自定义性。cherry-pick合并提交的时候是生成了新的commitid并不是Fast-forward合并模式，这点需要注意。题图引用： https://medium.com/faun/awesome-git-technique-for-partial-merge-7d64a7e62440文章部分参考： https://zhuanlan.…

使用Gogs配置git-hook部署代码
type: item
date: 2019-09-20T23:57:00+08:00
description: 在调研一个新项目的过程中需要使用git来提交修改代码，由于是调研阶段所以新项目代码没有使用公司的gitlab版本库。而是我自己搭建在了内网的一台测试服务器上面。所以就会用协同开发代码的拉取提交过程。所以第一想法就是使用git server来简单的部署一个git服务器。在加上git自带的hook可以进行代码的自动提交部署。然而之前了解到一个比gitlab更加轻量的代码仓库Gogs，而且常用的gitlab上的功能都有，最关键的是他是使用Go开发的，一个直接运行二进制文件部署，非常的方便。如果不想使用Gogs，你通用可以使用纯命令版本的部署方法，参考配置git-hook部署项目代码，原理都是一样的。只是Gogs提供的web版对新手还是挺友好的。环境要求Gogs需要很少的环境依赖如下：数据库（选择以下一项）：MySQL：版本 >= 5.7PostgreSQLMSSQLTiDB（实验性支持，使用 MySQL 协议连接）或者 什么都不安装 直接使用 SQLite3git（bash）：服务端和客户端均需版本 >= 1.7.1Windows 系统建议使用最新版SSH 服务器：如果您只使用 HTTP/HTTPS 的话请忽略此项如果您选择在 Windows 系统使用内置 SSH 服务器，请确保添加 ssh-keygen 到您的 %PATH% 环境变量中推荐 Windows 系统使用 Cygwin OpenSSH 或 CopsshWindows 系统 请确保 Bash 是默认的 Shell 程序，而不是 PowerShell由于我是部署PHP项目，所以我直接使用了MySQL，你也可以不用安装数据库，直接使用SQLite3。(对于个人SQLite3还是没啥问题，如果是团队中正式使用还是推荐正式一点的数据库，比如MySQL)以下的操纵我都是使用的CentOS7操作，对于Debian或Ubuntu命令做对应的替换就好了安装git如果你的系统上没有git，执行执行下面的命令安装即可。yum install -y git配置git用户创建git用户我们使用专门的git用户来管理，而且我们以后生成的clone地址类似git@wq.com:lepig/we7.git。useradd git密码可以先不用设置，因为我们后面主要是使用密钥的方式来提交代码。需要注意的是，我们不需要将git的登录shell修改为/usr/bin/git-shell，保持默认的/bin/bash就好。因为gogs会自动会git用户的shell进行限制ssh -T git@wq.com Hi there, You've successfully authenticated, but Gogs does not provide shell access. If this is unexpected, please log in with password and setup Gogs under another user.创建证书登录文件(authorized_keys)cd /home/git/ sudo -u git mkdir .ssh chmod 700 .ssh/ sudo -u git touch .ssh/authorized_keys chmod 600 .ssh/authorized_keys配置Gogs安装Gogs我使用的是二进制的部署方式，具体二进制文件可以到Gogs官网下载最新的版本。下载后得到一个压缩包gogs_0.11.91_linux_amd64.zip解压后会得到一个gogs目录我们只要执行下面的命令就OK了chown -R git:git gogs #给予git权限，不然无法启动服务 cd gogs sudo -u git ./gogs web #推荐使用-u参数来指定使用git用户来操作配置Gogs如果你是第一次启动正常情况会出现下面的输出，就表示启动成功，然后访问你的ip:3000端口[root@JDu4e00u53f7 gogs]# sudo -u git ./gogs web 2019/09/19 18:25:32 [ WARN] Custom config '/home/git/gogs/custom/conf/app.ini' not found, ignore this if you're running first time 2019/09/19 18:25:32 [TRACE] Custom path: /home/git/gogs/custom 2019/09/19 18:25:32 [TRACE] Log path: /home/git/gogs/log 2019/09/19 18:25:32 [TRACE] Log Mode: Con…

如何避免git pull时产生'Merge branch 'master' of...等类似操作
type: item
date: 2019-03-18T22:29:00+08:00
description: 在使用 Git 的进行代码版本控制的时候，往往会发现在 log 中出现 "Merge branch 'master' of ..." 这句话，如下图所示。日志中记录的一般为开发过程中对代码的改动信息，如果出现过多例如上述描述的信息会造成日志的污染。类似下面这样产生的原因当多人合作开发一个项目时，本地仓库落后于远程仓库是一个非常正常的事情，可参考下图。A-B-C(master)\ D(origin/master)具体情境如下：我当前拉取的远端版本为 B，此时修改了代码，并在本地仓库 commit 一次，但并未 push 到远端仓库。另一位开发者在 B 的基础上，同样 commit 了一次并 push 到远端仓库。那么这个时候，我再 push 自己的代码就会发生错误，如下。To github.com:xxx/xxx.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:xxx/xxx.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again.这个时候我们会选择，先 pull，再 push。Ok，push 成功，但是此时我们查看 log 就会发现除了我们自己提交的那条日志之外，会多出一条 "Merge branch 'master' of ..."。那么，为什么会出现这种现象呢？其实是与 Git 的工作原理有关，对 Git 比较了解的人应该会知道，无论是 pull、push 亦或是 merge 操作，其实背后都是有很多的不同的模式的。在进行 pull 操作的同时，其实就是 fetch+merge 的一个过程。我们从 remote 分支中拉取新的更新，然后再合并到本地分支中去。如果 remote 分支超前于本地分支，并且本地分支没有任何 commit 的，直接从 remote 进行 pull 操作，默认会采用 fast-forward 模式，这种模式下，并不会产生合并节点，也就是说不会产生多余的那条 log 信息如果想之前那样，本地先 commit 后再去 pull，那么此时，remote 分支和本地会分支会出现分叉，这个时候使用 pull 操作拉取更新时，就会进行分支合并，产生合并节点和 log 信息。这两种状态分别如下图所示：# fast-forword A-B-D(origin/master) \ C(master)# merge A-B-C-E(master) \ / D(origin/master)如何解决针对这种情况目前我总结了3中方法。在执行git pull的时候加上--rebase参数。这参数的意思就是在合并代码之前，先执行变基操作，成功后在进行真正的merge操作。(如果有冲突需要手动解决)当出现Merge branch 'master' of...这种交互窗口的时候你也可以直接使用:wq进行保存或者你也可以自己写点message，然后查看下git日志可以发现类似下面这样可以看到最终产生了一次提交(ccf4626)。那么这个时候不用怕，我们继续在命令行执行下git rebase然后在看看日志线是不是变回来了。就是这么的神奇。这个方法操作以后可以一劳永逸。在你的git bash里执行git config --global pull.rebase true。这个配置就是告诉git在每次pull前先进行rebase操作。这种方法和方法1原理一样，只不过方法1是每次pull前都要手动操作。总结什么时候使用merge？什么时候使用rebase？对于团队开发，当你在你自己的本地分支上完成开发时，你需要使用merge来合并你的修改到本地开发分支。当你每天打开电脑来拉取远程分支的时候，你最好使用rebase来操作，这样最直接的的好处是你们团队的commit message时间线会成一条笔直的直线。

Git从入门到精通[更新中...]
type: item
date: 2018-06-24T20:57:00+08:00
description: 本站为 Git 学习参考手册。目的是为学习与记忆 Git 使用中最重要、最普遍的命令提供快速翻阅。 这些命令以你可能需要的操作类型划分，并且将提供日常使用中需要的一些常用的命令以及参数。本手册将从入门到精通指导大家。 首先，我们要从如何以 Git 的思维方式管理源代码开始。如何以 GIT 的方式思考懂得 Git，第一件重要的事情就是要知道它与 Subversion、Perforce 或者任何你用过的版本控制工具都有着很大的差别。 通常，忘掉你预想的版本控制方式，改以 Git 的方式思考，能够帮助你更好地学习 Git。让我们从头开始。假设你正在设计一个新的源代码管理系统。在你使用某个工具之前，是如何完成基本的源码版本控制工作的呢？ 十有八九，你只是在项目到达某些阶段的时候，对项目做一份拷贝。 $ cp -R project project.bak这样，你就可以在事情变得一团糟的时候很方便的返回到之前的状态，或者通过对比当前的项目与之前的拷贝，看看自己在之后的工作中，都做了哪些修改。如果你有点偏执，你可能会经常作上面说的事情，或许还会给项目拷贝加个日期： $ cp -R project project.2010-06-01.bak如此，你就有了一堆项目在各个阶段的快照，来作比较、查看。使用这种模式，你还可以有效地与人分享项目变更。 如果你会在项目到达一定阶段的时候给它打个包，丢到自己的网站上，那其他的开发者们，就能很方便地下载它，做点改动，并给你补丁回馈。 $ wget http://example.com/project.2010-06-01.zip $ unzip project.2010-06-01.zip $ cp -R project.2010-06-01 project-my-copy $ cd project-my-copy $ (做了某些修改) $ diff project-my-copy project.2010-06-01 > change.patch $ (通过E-mail发送修改补丁)以此方式，原先的开发者就能将其他人的改动应用到他的项目中去，其他开发者也能了解你做的变更。其实这便是许多开源项目采用过多年的协作方式。这办法其实很好使，所以假设我们现在想要写个工具，让这个办法更快、更简单。 我们与其实现一个工具以记录每个文件的版本，可能不如去实现个工具以使创建、储存项目的快照更加方便，不用每次都去人肉作整个项目的拷贝。这就是 Git 的精要所在。你通过 git commit告诉 Git 你想保存一份项目快照， Git 就会为你的项目中的各个文件的当前状态存一份记录。之后，绝大部分的 Git 命令都围绕这些记录展开。 比如查看它们的区别（diff），提取它们的内容，等等。如果你将 Git 看作一个排序、对比以及合并项目更新的工具，那就容易理解状况和正确做事了。目录获取与创建项目Git使用前配置设置Git本地项目开发库默认路径配置本地用户和邮箱initclone基本的快照addstatusdiffcommitresetrm, mv分支与合并branchcheckoutmergelogtag分享与更新项目fetch, pullpushremote检查与比较logdiff一、获取与创建项目你得先有一个 Git 仓库，才能用它进行操作。仓库是 Git 存放你要保存的快照的数据的地方。拥有一个 Git 仓库的途径有两种。在已有的目录中，初始化一个新的，其一。 比如一个新的项目，或者一个已存在的项目，但该项目尚未有版本控制。如果你想要复制一份别人的项目， 或者与别人合作某个项目，也可以从一个公开的 Git 仓库克隆，其二。本章将对两者都做介绍。Git使用前配置如果设置了，在输入命令示界面可以很方便的使用复制和粘贴（用左键选取要复制的，点右键直接就可以复制，粘贴时只需点一下右键。）设置方法：Git Bash快捷图标（桌面图标）右键属性-选项，把快速编辑模式勾上就可以，如下图：设置Git本地项目开发库默认路径如果设置了，就不用每次打开Git再cd打开目录了。方法：右键Git Bash快捷图标（桌面图标）属性，找到快捷方式-起始位置，把你的项目地址放在这里就可以了。如下图：配置本地用户和邮箱用户名邮箱作用 : 我们需要设置一个用户名 和 邮箱, 这是用来上传本地仓库到GitHub中, 在GitHub中显示代码上传者;使用命令 :git config --global user.name "HanShuliang" //设置用户名 git config --global user.email "13241153187@163.com" //设置邮箱到此Git客户端已安装及GitHub配置完成，现在可以从GitHub传输代码了。gi…

Linux简易安装Git服务器
type: item
date: 2017-08-03T22:43:00+08:00
description: Git作为目前最先进的版本控制系统，基本上在日常的开发中已经离不开了。所以下面记录一下小团队使用自己内部的git服务器，进行多人协作开发。安装Git安装git是非常简单的，在CentOS上只需要执行下面的命令yum install git -y而如果是Ubuntu上可以使用下面的命令apt-get install git -y创建Git用户接着我们创建一个git用户来作为拉取代码时指定的用户useradd git这样默认就会在/home下生成一个以git为名字的目录。配置秘钥认证在我们拉取代码的过程中对于每次都输入密码来进行认证是很繁琐的一件事情。尽管可以把密码写在git的配置文件中，但这不是真正的免密码登录。所以使用密钥对来进行用户认证首先我们在自己的开发机上生成一下公钥和私钥ssh-keygen -t rsa -C "ooxx@qq.com"然后一路回车。不出意外会在当前用户的家目录下的.ssh目录下生成一组密钥对，分别是id_rsa和id_rsa.pub 前者为私钥后者为公钥。我们要做的就是把公钥的内容发送到git服务器中，然后我们在拉取代码的时候进行系统会自动进行秘钥对验证。ssh-copy-id -i .ssh/id_rsa.pub git@gitserver这时本地开发机的公钥就被自动发送到/home/git/.ssh/authorized_keys文件中。如果你的机器上没有ssh-copy-id这个命令，那么自己手动复制公钥内容，然后追加到authorized_keys文件中吧。这里需要注意，需要把.ssh目录的权限修改为700以及authorized_keys权限修改为600用户及所属组为git不然会出现拉取提示权限不正确的提示禁用git用户系统登录出于安全考虑，创建的git用户是不允许登录shell，这可以通过编辑/etc/passwd文件完成git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell创建仓库mkdir /srv/git cd /srv/git git init --bare laravel.git执行上述命令后会在/srv/git下生成一个laravel.git的目录，这就是我们的项目共享仓库。—bare就是代表创建一个裸仓库也就是不包含.git的目录。最后设置一下仓库的所有者为gitchown -R git.git laravel.git拉取仓库代码到目前为止，git服务器端的配置就已经配置完毕了。现在我们回到开发机器，执行下面命令拉取代码git clone git@gitserver:/srv/git/laravel.git错误提示新建一个文件/home/git/git-shell-commands/no-interactive-login其内容如下#!/bin/sh printf '%s\n' "Hi $USER! You've successfully authenticated, but I do not provide interactive shell access." exit 128chmod +x no-interactive-loginhttps://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E9%85%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1%E5%99%A8

Git Pull 避免用户名和密码方法
type: item
date: 2016-12-22T10:41:00+08:00
description: 记录不使用ssh-key方式pull或者push代码的时候免密码的问题。第一种方式git config --global credential.helper store执行完成后会在家目录下多出一个.gitconfig的文件，内容为：[credential] helper = store //store表示永久存储此时切换到你的项目根目录执行一次git pull那么这个时候会提示你输入用户名和密码，git会把这次的用户名和密码记录到当前登录用户家目录的.git-credentials文件中，如下：https://username:password@git.coding.net那么你下一次再次执行git pull的时候就不要求你输入密码了。通过这种方式配置的http或者https免密码方式还可以设置密码有效期，比如：git config --global credential.helper cache上面设置默认密码存储时间为15分钟，如果你想自己指定时间可以是使用--timeout选项:git config credential.helper 'cache --timeout=3600'第二种方式(推荐)增加远程地址的时候带上用户名和密码首先切换到你的项目根目录，执行：sudo git remote remove origin sudo git remote add origin https://username:password@git.coding.net/lepig/laravel.git至此就免密码进行git pull了。