Linux 部署Git服务端、Windows 配置Git客户端以及Git工作流程

原创 tiangr  2017-02-25 15:23  阅读 165 次

阿里云服务器环境:

CPU: 1核
内存: 2048 MB
操作系统: CentOS 7.2 64位

Linux 安装部署Git服务器端

  1. $ yum -y update
  2. $ yum install git  #安装Git

添加Git用户

  1. $ sudo useradd git
  2. $ sudo passwd  git  # 设置密码,为了方便操作,密码较为的简单
  3. $ sudo mkdir /home/git   # 设置 git 用户的工作目录
  4. $ sudo chown -R  git /home/git  #将工作目录的权限给git用户

*禁用shell登录:

出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:

git:x:1001:1001:,,,:/home/git:/bin/bash

改为:

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

在服务器端建立仓库

  1. $ su git    # 切换用户到git,在本实验中用户权限的使用很重要,之后会讲解
  2. mkdir -p /home/git/example/project.git  #创建仓库文件夹,-p 是指建立上层目录。
  3. $ cd /home/git/example/project.git
  4. $ git init  --bare  #初始化仓库

在客户端生成密钥

在管理 Git 项目上,有 HTTPS 和 SSH 两种方式,使用 HTTPS 每次提交都要输入用户名和密码,使用 SSH 需要先配置和添加好 SSH key。

如果是Linux下可以直接使用命令行

  1. $ ssh-keygen -t rsa #生成密钥,默认将放在家目录的 .ssh 文件夹中,并且不修改名字的话,默认密钥对名为 id_rsa
  2. $ cat ~/.ssh/id_rsa.pub | ssh git@localhost "mkdir -p ~/.ssh && cat >>  ~/.ssh/authorized_keys"   # 将公钥发送给远程端

但如果客户端在windows下就需要下载git-for-windows https://git-for-windows.github.io/ 。

Windows 配置Git客户端

检查本机是否有ssh key设置

$ cd ~/.ssh 或cd .ssh

如果没有则提示: No such file or directory

如果有则进入~/.ssh路径下(ls查看当前路径文件,rm * 删除所有文件)

使用Git Bash生成新的ssh key

  1. $ cd ~  #保证当前路径在”~”下
  2. $ ssh-keygen -t rsa -C "xxxxxx@yy.com"  #建议填写自己真实有效的邮箱地址
  3. Generating public/private rsa key pair.
  4. Enter file in which to save the key (/c/Users/xxxx_000/.ssh/id_rsa):   #不填直接回车
  5. Enter passphrase (empty for no passphrase):   #输入密码(可以为空)
  6. Enter same passphrase again:   #再次确认密码(可以为空)
  7. Your identification has been saved in /c/Users/xxxx_000/.ssh/id_rsa.   #生成的密钥
  8. Your public key has been saved in /c/Users/xxxx_000/.ssh/id_rsa.pub.  #生成的公钥
  9. The key fingerprint is:
  10. e3:51:33:xx:xx:xx:xx:xxx:61:28:83:e2:81 xxxxxx@yy.com
  11. *本机已完成ssh key设置,其存放路径为:c:/Users/xxxx_000/.ssh/下。
  12. 注释:可生成ssh key自定义名称的密钥,默认id_rsa。
  13. $ ssh-keygen -t rsa -C "邮箱地址" -f ~/.ssh/git_keys   #生成ssh key的名称为git_keys,慎用容易出现其它异常。

复制id_rsa.pub的公钥内容。 进入c:/Users/xxxx_000/.ssh/目录下,打开id_rsa.pub文件,全选复制公钥内容。 写入至服务器端的文件 ~/.ssh/authorized_keys,这样就可以使用SSH连接Git服务器。

在客户端建立仓库

  1. $ git config --global user.name “your_username”  #设置用户名
  2. $ git config --global user.email “your_registered_github_Email”  #设置邮箱地址

创建一个文件测试效果

  1. $ vim readme      #创建一个文档来测试提交的效果
  2. $ git add .
  3. $ git commit -m "test"
  4. $ git remote add origin git@localhost:/home/git/example/project.git
  5. $ git push origin master

检验效果

  1. $ cd /home
  2. $ git clone git@localhost:/home/git/example/project.git

新增客户端用户

如果团队中有个新用户要进行协作,我们只要重复上面新增客户端用户的方法,

  1. $ ssh-keygen -t rsa -C "*********@qq.com" -f ~/.ssh/git_keys

然后把生成的公钥追加至文件~/.ssh/authorized_keys,记得要用换行符隔开,格式就像下面这样:

ssh-rsa AAAAB3NzaC1yc2EAAaaaaaaupeyE1NMMrb121244DwhwFLsPFiFrFb1QUwQtX2m/YSi8ELn3Vga/5AhfKKPWG+nOczWZxi0XguiyAslRiiowXaUjBYei5NHHBcAy+GiZWs4u8h3ZU7uGvwmQlqHf8tQ/I0J1RNR6nQ8Ra9882398akk23h9Hhp63EagSbpkefg7qScroq0+VZ2yfLyjUCLgxhb+Eah+r9EqQ4l%HEF;asd8hLQw449W1SzKz3hCwxFAJFKbj/n+J50vNXB3fLNeTNiq@OOIkn324n802Do5jIZGFzNrYsIRFbJVbHvIsodyXDmz6Qbqlx87xmEQ== admaaa@163.com
ssh-rsa AAAAB3NzaC1yc2EAAAaa2#@8923n(&@hfg2-hg9002nkglsdfPCBUhDN185+jyoJQRwLImRr6IOwh/LSBS1N22pO#NG3434ng90u32n@0)@#NKDLHWO:@_jqtUIBr8UzWzliM5Zcn9U/DjSjuAiP/SFg1JEoXfWSFToWQpYNbGS9VFwU83MH1iGGDUeaeHY5mAMWy57ym/+Jm/hPs1I3E+OtDT9+K1RyIGr44Ur7aWpKZ/PMgiuPUc6qfGFVP4xvRw== myyyy@gmail.com

进入到需要存放文件的本地目录,拉取远程仓库:

  1. git clone git@localhost:/home/git/gzt3.com/project.git

工作流程:

git的基本流程如下:

  1. 创建或修改文件
  2. 使用git add命令添加新创建或修改的文件到本地的缓存区(Index)
  3. 使用git commit命令提交到本地代码库
  4. (可选,有的时候并没有可以同步的远端代码库)使用git push命令将本地代码库同步到远端代码库

使用git status命令查看当前git仓库的状态:

  1. $ git status
  2. On branch master
  3. Initial commit
  4. Untracked files:
  5.    (use "git add <file>...") to include in what will be committed)
  6.        file1
  7.        file2
  8.        file3
  9. nothing added to commit but untracked files present (use "git add" to track)

可以发现,有三个文件处于untracked状态,下一步我们就需要用git add命令将他们加入到缓存区(Index)。

使用git add命令将新建的文件添加到:

  1. $ git add file1 file2 file3

然后再次执行git status就会发现新的变化:

  1. $ git status
  2. On branch master
  3. Initial commit
  4. Changes to be committed:
  5.     (use "git rm --cached <file>..." to unstage)
  6.        new file: file1
  7.        new file: file2
  8.        new file: file3

你现在为commit做好了准备,你可以使用 git diff 命令再加上 --cached 参数,看看缓存区中哪些文件被修改了。进入到git diff --cached界面后需要输入q才可以退出:

  1. $ git diff --cached

如果没有--cached参数,git diff 会显示当前你所有已做的但没有加入到索引里的修改。

如果你要做进一步的修改, 那就继续做, 做完后就把新修改的文件加入到缓存区中。

当所有新建,修改的文件都被添加到了缓存区,我们就要使用git commit提交到本地仓库:

  1. $ git commit -m "add 3 files"

需要使用-m添加本次修改的注释,完成后就会记录一个新的项目版本。除了用git add 命令,我们还可以用下面的命令将所有没有加到缓存区的修改也一起提交,但-a命令不会添加新建的文件。

  1. $ git commit -a -m "add 3 files"

再次输入git status查看状态,会发现当前的代码库已经没有待提交的文件了,缓存区已经被清空。

至此,我们完成了第一次代码提交,这次提交的代码中我们创建了三个新文件。需要注意的是如果是修改文件,也需要使用git add命令添加到缓存区才可以提交。如果是删除文件,则直接使用git rm命令删除后会自动将已删除文件的信息添加到缓存区,git commit提交后就会将本地仓库中的对应文件删除。

这个时候如果本地的仓库连接到了远程Git服务器,可以使用下面的命令将本地仓库同步到远端服务器:

  1. $ git push origin master

分支与合并

Git的分支可以让你在主线(master分支)之外进行代码提交,同时又不会影响代码库主线。分支的作用体现在多人协作开发中,比如一个团队开发软件,你负责独立的一个功能需要一个月的时间来完成,你就可以创建一个分支,只把该功能的代码提交到这个分支,而其他同事仍然可以继续使用主线开发,你每天的提交不会对他们造成任何影响。当你完成功能后,测试通过再把你的功能分支合并到主线。

1.分支

一个Git仓库可以维护很多开发分支。现在我们来创建一个新的叫 experimental的分支:

  1. $ git branch experimental

运行git branch命令可以查看当前的分支列表,以及目前的开发环境处在哪个分支上:

  1. $ git branch
  2.  experimental
  3. * master

experimental 分支是你刚才创建的,master分支是Git系统默认创建的主分支。星号标识了你当工作在哪个分支下,输入git checkout 分支名可以切换到其他分支:

  1. $ git checkout experimental
  2. Switched to branch 'experimental'

切换到experimental分支,切换完成后,先编辑里面的一个文件,再提交(commit)改动,最后切换回 “master”分支:

  1. # 修改文件file1
  2. $ echo "update" >> file1
  3. # 查看当前状态
  4. $ git status
  5. # 添加并提交file1的修改
  6. $ git add file1
  7. $ git commit -m "update file1"
  8. # 查看file1的内容
  9. $ cat file1
  10. test
  11. update
  12. # 切换到master分支
  13. $ git checkout master

查看下file1中的内容会发现刚才做的修改已经看不到了。因为刚才的修改时在experimental分支下,现在切换回了master分支,目录下的文件都是master分支上的文件了。

现在可以在master分支下再作一些不同的修改:

  1. # 修改文件file2
  2. $ echo "update again" >> file2
  3. # 查看当前状态
  4. $ git status
  5. # 添加并提交file2的修改
  6. $ git add file2
  7. $ git commit -m "update file2 on master"
  8. # 查看file2的内容
  9. $ cat file2
  10. test
  11. update again

这时,两个分支就有了各自不同的修改,分支的内容都已经不同,如何将多个分支进行合并呢?

可以通过下面的git merge命令来合并experimental到主线分支master:

  1. # 切换到master分支
  2. $ git checkout master
  3. # 将experimental分支合并到master
  4. $ git merge  -m 'merge experimental branch' experimental

-m参数仍然是需要填写合并的注释信息。

由于两个branch修改了两个不同的文件,所以合并时不会有冲突,执行上面的命令后合并就完成了。

如果有冲突,比如两个分支都改了一个文件file3,则合并时会失败。首先我们在master分支上修改file3文件并提交:

  1. # 切换到master分支
  2. $ git checkout master
  3. # 修改file3文件
  4. $ echo "master: update file3" >> file3
  5. # 提交到master分支
  6. $ git commit -a -m 'update file3 on master'

然后切换到experimental,修改file3并提交:

  1. # 切换到experimental分支
  2. $ git checkout experimental
  3. # 修改file3文件
  4. $ echo "experimental: update file3" >> file3
  5. # 提交到master分支
  6. $ git commit -a -m 'update file3 on experimental'

切换到master进行合并:

  1. $ git checkout master
  2. $ git merge experimental
  3. Auto-merging file3
  4. CONFLICT (content): Merge conflict in file3
  5. Automatic merge failed; fix conflicts and then commit the result.

合并失败后先用git status查看状态,会发现file3显示为both modified,查看file3内容会发现:

  1. $ cat file3
  2. test
  3. <<<<<<< HEAD
  4. master: update file3
  5. =======
  6. experimental: update file3
  7. >>>>>>> experimental

上面的内容也可以使用git diff查看,先前已经提到git diff不加参数可以显示未提交到缓存区中的修改内容。

可以看到冲突的内容都被添加到了file3中,我们使用vim编辑这个文件,去掉git自动产生标志冲突的<<<<<<等符号后,根据需要只保留我们需要的内容后保存,然后使用git add file3git commit命令来提交合并后的file3内容,这个过程是手动解决冲突的流程。

  1. # 编辑冲突文件
  2. $ vim file3
  3. # 提交修改后的文件
  4. $ git add file3
  5. $ git commit -m 'merge file3'

当我们完成合并后,不再需要experimental时,可以使用下面的命令删除:

  1. $ git branch -d experimental

git branch -d只能删除那些已经被当前分支的合并的分支. 如果你要强制删除某个分支的话就用git branch –D

2.撒销一个合并

如果你觉得你合并后的状态是一团乱麻,想把当前的修改都放弃,你可以用下面的命令回到合并之前的状态:

  1. $ git reset --hard HEAD^
  2. # 查看file3的内容,已经恢复到合并前的master上的文件内容
  3. $ cat file3

3.快速向前合并

还有一种需要特殊对待的情况,在前面没有提到。通常,一个合并会产生一个合并提交(commit), 把两个父分支里的每一行内容都合并进来。

但是,如果当前的分支和另一个分支没有内容上的差异,就是说当前分支的每一个提交(commit)都已经存在另一个分支里了,git 就会执行一个“快速向前"(fast forward)操作;git 不创建任何新的提交(commit),只是将当前分支指向合并进来的分支。

分布式的工作流程

你目前的项目在/home/shiyanlou/gitproject目录下,这是我们的git 仓库(repository),另一个用户也想与你协作开发。他的工作目录在这台机器上,如何让他提交代码到你的git仓库呢?

首先,我们假设另一个用户也用shiyanlou用户登录,只是工作在不同的目录下开发代码,实际工作中不太可能发生,大部分情况都是多个用户,这个假设只是为了让实验简化。

该用户需要从git仓库进行克隆:

  1. # 进入到临时目录
  2. $ cd /tmp
  3. # 克隆git仓库
  4. $ git clone /home/shiyanlou/gitproject myrepo
  5. $ ls -l myrepo
  6. -rw-rw-r-- 1 shiyanlou shiyanlou 31 Dec 22 08:24 README.md
  7. -rw-rw-r-- 1 shiyanlou shiyanlou  9 Dec 22 08:24 file1

这就建了一个新的叫"myrepo"的目录,这个目录里包含了一份gitproject仓库的克隆。这份克隆和原始的项目一模一样,并且拥有原始项目的历史记录。

在myrepo做了一些修改并且提交:

  1. $ cd myrepo
  2. # 添加新的文件newfile
  3. $ echo "newcontent" > newfile
  4. # 提交修改
  5. $ git add newfile
  6. $ git commit -m "add newfile"

myrepo修改完成后,如果我们想合并这份修改到gitproject的git仓库该如何做呢?

可以在仓库/home/shiyanlou/gitproject中把myrepo的修改给拉 (pull)下来。执行下面几条命令:

  1. $ cd /home/shiyanlou/gitproject
  2. $ git pull /tmp/myrepo master
  3. remote: Counting objects: 5, done.
  4. remote: Compressing objects: 100% (2/2), done.
  5. remote: Total 3 (delta 0), reused 0 (delta 0)
  6. Unpacking objects: 100% (3/3), done.
  7. From /tmp/myrepo
  8.  * branch            master     -> FETCH_HEAD
  9. Updating 8bb57aa..866c452
  10. Fast-forward
  11.  newfile | 1 +
  12.  1 file changed, 1 insertion(+)
  13.  create mode 100644 newfile
  14. # 查看当前目录文件
  15. $ ls                                                                                                    [8:28:02]
  16. README.md  file1  newfile

这就把myrepo的主分支合并到了gitproject的当前分支里了。

如果gitproject在myrepo修改文件内容的同时也做了修改的话,可能需要手工去修复冲突。

如果你要经常操作远程分支(remote branch),你可以定义它们的缩写:

  1. $ git remote add myrepo /tmp/myrepo

git pull命令执行两个操作: 它从远程分支(remote branch)抓取修改git fetch的内容,然后把它合并git merge进当前的分支。

gitproject里可以用git fetch 来执行git pull前半部分的工作, 但是这条命令并不会把抓下来的修改合并到当前分支里:

  1. $ git fetch myrepo
  2. From /tmp/myrepo
  3.  * [new branch]      master     -> myrepo/master

获取后,我们可以通过git log查看远程分支做的所有修改,由于我们已经合并了所有修改,所以不会有任何输出:

  1. $ git log -p master..myrepo/master

当检查完修改后,gitproject可以把修改合并到它的主分支中:

  1. $ git merge myrepo/master
  2. Already up-to-date.

如果我们在myrepo目录下执行git pull会发生什么呢?

myrepo会从克隆的位置拉取代码并更新本地仓库,就是把gitproject上的修改同步到本地:

  1. # 进入到gitproject
  2. $ cd /home/shiyanlou/gitproject
  3. # 添加一行内容到newfile
  4. $ echo "gitproject: new line" >> newfile
  5. # 提交修改
  6. $ git commit -a -m 'add newline to newfile'
  7. [master 8c31532] add newline to newfile
  8.  1 file changed, 1 insertion(+)
  9. # 进入myrepo目录
  10. $ cd /tmp/myrepo
  11. # 同步gitproject的所有修改
  12. $ git pull
  13. remote: Counting objects: 6, done.
  14. remote: Compressing objects: 100% (2/2), done.
  15. remote: Total 3 (delta 1), reused 0 (delta 0)
  16. Unpacking objects: 100% (3/3), done.
  17. From /home/shiyanlou/gitproject
  18.    8bb57aa..8c31532  master     -> origin/master
  19. Updating 866c452..8c31532
  20. Fast-forward
  21.  newfile | 1 +
  22.  1 file changed, 1 insertion(+)

因为myrepo是从gitproject仓库克隆的,那么他就不需要指定gitproject仓库的地 址。因为Git把gitproject仓库的地址存储到myrepo的配置文件中,这个地址就是在git pull时默认使用的远程仓库:

  1. $ git config --get remote.origin.url
  2. /home/shiyanlou/gitproject

如果myrepo和gitproject在不同的主机上,可以通过ssh协议来执行clone 和pull操作:

  1. $ git clone localhost:/home/shiyanlou/gitproject test

这个命令会提示你输入shiyanlou用户的密码,用户密码随机,可以点击屏幕上方的SSH按钮查看。

常见问题:

  1. 遇到权限错误怎么办?

之所以会这样,是因为 Git 服务是由 git 这个用户来操作的,现在改变了 /home/git 的所有权,git 这个用户无法操作里面的文件,所以报错了,解决这个问题的办法就是将 它的权限交给 git 这个用户。

相关链接:

https://jingyan.baidu.com/album/a65957f4e91ccf24e77f9b11.html - window下配置SSH连接GitHub、GitHub配置ssh key

http://www.ruanyifeng.com/blog/2012/07/git.html - Git分支管理策略

http://www.ruanyifeng.com/blog/2015/12/git-workflow.html - Git 工作流程

http://www.ruanyifeng.com/blog/2015/08/git-use-process.html - Git 使用规范流程

http://www.ruanyifeng.com/blog/2014/06/git_remote.html - Git远程操作详解

http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html - 常用 Git 命令清单

https://www.shiyanlou.com/courses/616/labs/2058/document

linux管理多个ssh公钥密钥

http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137583770360579bc4b458f044ce7afed3df579123eca000

特别提示:本站资源全部免费下载,因服务器需经费维护,文中部分外链点击后会进入广告,请耐心等待5秒即可跳过广告进入目标页面。如遇页面外链打不开或下载地址失效,您可以在评论中指出错误,或扫描页面底部二维码。
本文地址:http://www.tiangr.com/linux-bu-shu-git-fu-wu-duan-windows-pei-zhi-git-ke-hu-duan-git-workflow.html
版权声明:本文为原创文章,版权归 tiangr 所有,欢迎分享本文,转载请保留出处!

发表评论


表情