zoukankan      html  css  js  c++  java
  • Git分布式版本控制系统

    1.linux 安装git 

    sudo apt-get install git

    创建版本库(当前文件夹为工作空间)

    $ git init
    Initialized empty Git repository in d:/localresporty/.git/

    版本库(Repository)

    工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。具体参考http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013745374151782eb658c5a5ca454eaa451661275886c6000

    Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

    git-repo

    在当前文件夹下创建文件

    $ touch a.txt

    第一步,用命令git add告诉Git,把文件修改添加到暂存区

    $ git add a.txt

    第二步,用命令git commit告诉Git,把暂存区的所有内容提交到当前分支:Git自动为我们创建了唯一一个master分支

    $ git commit -m "zhu shi 1"

    第三步

    $ git push origin brandon.ma

    完成

    二:版本回退

    1 . 查看当前仓库当前的状态

    $ git status

    2. 查看文件作了什么修改(且没有add到仓库

    $ git diff a.txt
    diff --git a/a.txt b/a.txt
    index 9ac30bc..8c9534b 100644
    --- a/a.txt
    +++ b/a.txt
    @@ -1 +1 @@
    -this is two .
    +this is tw .^M

    3.显示从最近到最远的提交日志

    $ git log
    commit 04853c688c41d72e2efcb34f59b163bdaae6b17c
    Author: Brandon Ma <brandonma@augmentum.com.cn>
    Date:   Sat Jul 15 15:37:46 2017 +0800
    
        zhu shi 3
    
    commit 05b8bcec10435f2d688c536ffc10a74df7cd25c7
    Author: Brandon Ma <brandonma@augmentum.com.cn>
    Date:   Sat Jul 15 15:33:54 2017 +0800
    
        zhu shi 2
    
    commit 4080700e24a3714edba71deb34072d754a48245f
    Author: Brandon Ma <brandonma@augmentum.com.cn>
    Date:   Sat Jul 15 15:28:23 2017 +0800
    
        zhu shi 1
    $ git log --pretty=oneline   只显示 commit id
    04853c688c41d72e2efcb34f59b163bdaae6b17c zhu shi 3
    05b8bcec10435f2d688c536ffc10a74df7cd25c7 zhu shi 2
    4080700e24a3714edba71deb34072d754a48245f zhu shi 1

    在Git中,用HEAD表示当前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。回到上一个版本

    ,也可写commit id

    $ git reset --hard HEAD^
    HEAD is now at 05b8bce zhu shi 2

    $ cat a.txt    文件以回到上个版本
    this is two .

    后悔了若要回到新的版本

    $ git reflog   查找所有的记录
    05b8bce HEAD@{0}: reset: moving to HEAD^
    04853c6 HEAD@{1}: commit: zhu shi 3
    05b8bce HEAD@{2}: commit: zhu shi 2
    4080700 HEAD@{3}: commit (initial): zhu shi 1
    $ git reset --hard 4080700   回到新的版本
    HEAD is now at 4080700 zhu shi 1

    丢弃工作区的修改

    $ git checkout -- a.txt

    命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,

    场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file

    场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。

    场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。

    没有--,就变成了“切换到另一个分支”的命令

    4. 删除文件

    $ rm  a.txt
    
    $ git rm a.txt   确实要从版本库中删除该文件

    $ git commit -m "buxiang yao le " 提交

    误删的话 ,相当于修改后后悔 , 返回版本库操作

    $ git checkout --file

    三 ,远程仓库操作

    第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsaid_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:

    $ ssh-keygen -t rsa -C "youremail@example.com"

    在用户主目录里找到.ssh目录,里面有id_rsaid_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

    第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:

    然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:

    github-addkey-1

    关联远程库并推送本地库

    $ git remote add origin git@github.com:maxingzheng/mxz.git
    推送master分支的所有内容
    $ git push -u origin master
    从远程克隆一个本地库
    $ git clone git@github.com:maxingzheng/mxz.git

    四.分支管理

    git-br-create

    当前在dev分支上

    git-br-dev-fd

    假如我们在dev上的工作完成了,就可以合并

    1.创建dev分支 

    $ git branch brandon  创建分支
    
    Brandon.Ma@WT01395 /D/mxz (master)
    $ git checkout brandon  切换分支
    Switched to branch 'brandon'
    
    Brandon.Ma@WT01395 /D/mxz (brandon)

    git checkout命令加上-b参数表示创建并切换

    当在dev分支上进行一系列操作后,可以切换到master进行合并

    $ git merge dev
    合并完后删除dev分支
    $ git branch -d dev

    冲突

    master分支和feature1分支各自都分别有新的提交,变成了这样:

    git-br-feature1

    必须首先解决冲突。解决冲突后,再提交,合并完成。

    git log --graph命令可以看到分支合并图。

    分支管理策略

    阅读: 473979

    通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

    如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

    下面我们实战一下--no-ff方式的git merge

    首先,仍然创建并切换dev分支:

    $ git checkout -b dev
    Switched to a new branch 'dev'
    

    修改readme.txt文件,并提交一个新的commit:

    $ git add readme.txt 
    $ git commit -m "add merge"
    [dev 6224937] add merge
     1 file changed, 1 insertion(+)
    

    现在,我们切换回master

    $ git checkout master
    Switched to branch 'master'
    

    准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward

    $ git merge --no-ff -m "merge with no-ff" dev
    Merge made by the 'recursive' strategy.
     readme.txt |    1 +
     1 file changed, 1 insertion(+)
    

    因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

    合并后,我们用git log看看分支历史:

    $ git log --graph --pretty=oneline --abbrev-commit
    *   7825a50 merge with no-ff
    |
    | * 6224937 add merge
    |/
    *   59bc1cb conflict fixed
    ...
    

    可以看到,不使用Fast forward模式,merge后就像这样:

    git-no-ff-mode


    分支策略

    在实际开发中,我们应该按照几个基本原则进行分支管理:

    首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

    那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

    你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

    所以,团队合作的分支看起来就像这样:

    git-br-policy

    修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;

    当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

    删除未合并的分支

    开发一个新feature,最好新建一个分支;

    如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除

    多人协作

    要查看远程库的信息,用git remote

    $ git remote -v
    origin  git@github.com:maxingzheng/mxz.git (fetch)
    origin  git@github.com:maxingzheng/mxz.git (push)

    多人协作

    阅读: 499364

    当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin

    要查看远程库的信息,用git remote

    $ git remote
    origin
    

    或者,用git remote -v显示更详细的信息:

    $ git remote -v
    origin  git@github.com:michaelliao/learngit.git (fetch)
    origin  git@github.com:michaelliao/learngit.git (push)
    

    上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。

    推送分支

    推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

    $ git push origin 分支名

    抓取分支

    当你的小伙伴从远程库clone时,默认情况下,只能看到本地的master分支。git branch命令看看:

    $ git branch
    * master
    

    要在dev分支上开发,就必须创建远程origindev分支到本地,于是他用这个命令创建本地dev分支:

    $ git checkout -b dev origin/dev
    

    现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程:

    $ git push origin 分支名
    1. 首先,可以试图用git push origin branch-name推送自己的修改;

    2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

    3. 如果合并有冲突,则解决冲突,并在本地提交;

    4. 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!

    如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name

    • 命令git tag <name>用于新建一个标签,默认为HEAD,也可以指定一个commit id;

    • git tag -a <tagname> -m "blablabla..."可以指定标签信息;

    • git tag -s <tagname> -m "blablabla..."可以用PGP签名标签;

    • 命令git tag可以查看所有标签。

      • 命令git push origin <tagname>可以推送一个本地标签;

      • 命令git push origin --tags可以推送全部未推送过的本地标签;

      • 命令git tag -d <tagname>可以删除一个本地标签;

      • 命令git push origin :refs/tags/<tagname>可以删除一个远程标签。

    标签

    给当前分支打上标签  默认标签是打在最新提交的commit上的

    $ git tag v1.0 (commitid)

    让Git显示颜色,会让命令输出看起来更醒目:

    $ git config --global color.ui true
    • 忽略某些文件时,需要编写.gitignore

    • .gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理

    搭建Git服务器

    第一步,安装git

    $ sudo apt-get install git
    

    第二步,创建一个git用户,用来运行git服务:

    $ sudo adduser git
    

    第三步,创建证书登录:

    收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

    第四步,初始化Git仓库:

    先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:

    $ sudo git init --bare sample.git
    

    Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git

    $ sudo chown -R git:git sample.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每次一登录就自动退出。

    第六步,克隆远程仓库:

    现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:

    $ git clone git@server:/srv/sample.git
    Cloning into 'sample'...
    warning: You appear to have cloned an empty repository.
    

    剩下的推送就简单了。

    管理公钥

    如果团队很小,把每个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。如果团队有几百号人,就没法这么玩了,这时,可以用Gitosis来管理公钥。

    这里我们不介绍怎么玩Gitosis了,几百号人的团队基本都在500强了,相信找个高水平的Linux管理员问题不大。

    管理权限

    有很多不但视源代码如生命,而且视员工为窃贼的公司,会在版本控制系统里设置一套完善的权限控制,每个人是否有读写权限会精确到每个分支甚至每个目录下。因为Git是为Linux源代码托管而开发的,所以Git也继承了开源社区的精神,不支持权限控制。不过,因为Git支持钩子(hook),所以,可以在服务器端编写一系列脚本来控制提交等操作,达到权限控制的目的。Gitolite就是这个工具。

    这里我们也不介绍Gitolite了,不要把有限的生命浪费到权限斗争中。

    参考:廖学锋 http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

  • 相关阅读:
    保险精算导论
    天津大学C语言程序设计
    会计学
    WIN10 CH340安装失败
    好用的浏览器插件
    好用的壁纸软件
    30讲 窗口看门狗
    STM32替换Arduino直通车
    stm32系列芯片独立看门狗(IWDG)溢出时间计算原理
    AD 电子元器件图片、名称及符号对照
  • 原文地址:https://www.cnblogs.com/mxz1994/p/7183728.html
Copyright © 2011-2022 走看看