美文网首页学习笔记
Git版本控制系统

Git版本控制系统

作者: 酷酷的红帽子 | 来源:发表于2019-03-26 08:21 被阅读0次

    集中式vs分布式

    • 集中式CVS、SVN

      • 速度慢,必须联网,开源精神不符
      • 版本库集中放在中央服务器,工作时,获取最新版本,工作完成后,再推送给中央服务器!
    • 分布式

      • 无中央服务器,每个人的电脑都是一个完整的版本库
      • 安全性能更高
      • 通常有一台充当“中央服务器”的电脑,仅仅作为方便“交换”大家的修改

    安装使用

    Yum安装:
    [root@node1 ~]# yum install git -y
    
    为node1上所有的git仓库设置用户名和Email
    [root@node1 ~]# git config --global user.name "Your Name"
    [root@node1 ~]# git config --global user.email "email@example.com"
    
    创建并初始化版本库
    [root@node1 ~]# mkdir firstgit && cd firstgit/ && git init && ls -ah
    Initialized empty Git repository in /root/firstgit/.git/
    .  ..  .git 
    .git目录作用:跟踪管理版本库
    
    
    • 所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。

    常规操作

    1.把文件添加到仓库中
    [root@node1 firstgit]# echo "hello world" > readme.txt
    [root@node1 firstgit]# git add readme.txt # 添加到仓库中
    [root@node1 firstgit]# git commit -m "write a readme.txt file" #提交并通过-m参数说明
    [master (root-commit) e380d2c] write a readme.txt file
     1 file changed, 1 insertion(+)
     create mode 100644 readme.txt
     
    2.修改文件内容,查询内容和状态并提交
    [root@node1 firstgit]# echo "hello eagleslab" > readme.txt
    [root@node1 firstgit]# git status # 查询当前git仓库状态,readme.txt 需要添加和提交
    # On branch master
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #   modified:   readme.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@node1 firstgit]# git diff readme.txt  # 变化的内容
    diff --git a/readme.txt b/readme.txt
    index aa982b7..8d0e700 100644
    --- a/readme.txt
    +++ b/readme.txt
    @@ -1 +1 @@
    -hello world\n hello git
    +hello eagleslab
    [root@node1 firstgit]# git add readme.txt 
    [root@node1 firstgit]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #   modified:   readme.txt
    #
    [root@node1 firstgit]# git commit -m "change messages"
    [master 7b92afb] change messages
     1 file changed, 1 insertion(+), 1 deletion(-)
    [root@node1 firstgit]# git status
    # On branch master
    nothing to commit, working directory clean
    
    3.查询历史记录并版本退回
    [root@node1 firstgit]# git log
    commit 3efa7f0fc058f00b0a98171fb77b44ab31481c87 # 版本ID
    Author: Cokeku <1154283293@qq.com>
    Date:   Mon Mar 18 22:42:38 2019 -0400
        add zj
    commit 7b92afbb9f118f7ae10c49abc3114e4ee91ed26a
    Author: Cokeku <1154283293@qq.com>
    Date:   Mon Mar 18 22:37:05 2019 -0400
        change messages
    commit e380d2cc936e01e17065408000c42c21f114321a
    Author: Cokeku <1154283293@qq.com>
    Date:   Mon Mar 18 22:31:25 2019 -0400
        write a readme.txt file
    [root@node1 firstgit]# git reset --hard e380d2cc936e01e17065408000c42c21f114321a # 退回指定版本
    HEAD is now at e380d2c write a readme.txt file
    [root@node1 firstgit]# cat readme.txt 
    hello world
    [root@node1 firstgit]# git reset --hard 3efa7f0fc058f00b0a98171fb77b44ab31481c87
    HEAD is now at 3efa7f0 add zj
    [root@node1 firstgit]# cat readme.txt 
    hello eagleslab zhengjiang!
    
    记录每一次的命令:
    [root@node1 firstgit]# git reflog
    3efa7f0 HEAD@{0}: reset: moving to 3efa7f0fc058f00b0a98171fb77b44ab31481c87
    e380d2c HEAD@{1}: reset: moving to e380d2cc936e01e17065408000c42c21f114321a
    3efa7f0 HEAD@{2}: commit: add zj
    7b92afb HEAD@{3}: commit: change messages
    e380d2c HEAD@{4}: commit (initial): write a readme.txt file
    
    
    • 控制版本历史记录:因为git内部有个Head指针指向当前的版本,如果需要退回版本,只需要将Head指针指向相对应的版本号,并且更新工作区文件。

    工作区和暂存区

    • 工作区:当前所在的firstgit目录就是一个工作区

    • .git不算工作区,只是Git的版本库

      • 版本库中有暂存区和自动创建的master分支及指向master的一个指针HEAD]
      • git add:将修改后文件添加到暂存区
      • git commit:将暂存区的所有文件提交到master分支上
      • git跟踪的是每次修改而不是文件,如果不将修改添加到暂存区是无法加入commit中的
    • 撤销修改

      • 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
      • 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了场景1,第二步按场景1操作
      • 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,版本退回即可,不过前提是没有推送到远程库
    • 删除文件

    [root@node1 firstgit]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add/rm <file>..." to update what will be committed) # 先删除再提交
    #   (use "git checkout -- <file>..." to discard changes in working directory) # 将版本库中的最新内容同步到工作区
    #   deleted:    readme.tx
    

    *远程仓库

    Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。有一台机器有一个原始版本库,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。

    1.注册Github账号
    2.创建SSH Key
    $ ssh-keygen -t rsa -C "youremail@example.com"
    3.登陆Github将id_rsa.pub文件的内容添加到SHH Key页面中
    
    PS:
    GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
    
    当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
    
    • 添加远程仓库
      注册登录Github
      根据提示信息:

      • 在命令行中创建新的仓库并关联
      • 在命令行中关联已经存在的仓库
      • git push命令:把当前分支master推送到远程
    • 从远程库克隆

      • 先前我们都是先创建本地库然后关联远程库
      • 现在最佳实践是先创建远程库然后克隆到本地,但是创建远程库的时候选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件。

    分支管理

    • 问题:假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

    • 分支的作用:创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

    快速合并

    创建与合并分支
    [root@node1 Shell]# git checkout -b dev
    Switched to a new branch 'dev'
    [root@node1 Shell]# git branch
    * dev
      master
    [root@node1 Shell]# cat 1.txt 
    [root@node1 Shell]# echo "This is dev operation" > 1.txt 
    [root@node1 Shell]# git add 1.txt 
    [root@node1 Shell]# git commit -m "eagels"
    [dev 1a3e0b5] eagels
     1 file changed, 2 insertions(+)
    [root@node1 Shell]# git checkout master
    [root@node1 Shell]# cat 1.txt 
    [root@node1 Shell]# git merge dev
    Updating d55b0d3..1a3e0b5
    Fast-forward
     1.txt | 2 ++
     1 file changed, 2 insertions(+)
    [root@node1 Shell]# cat 1.txt 
    This is dev operation
    hello
    [root@node1 Shell]# git branch -d dev
    Deleted branch dev (was 1a3e0b5)
    
    命令:
    查看分支:git branch
    创建分支:git branch <name>
    切换分支:git checkout <name>
    创建+切换分支:git checkout -b <name>
    合并某分支到当前分支:git merge <name>
    删除分支:git branch -d <name>
    

    冲突合并

    [root@node1 Shell]# git checkout -b test
    Switched to a new branch 'test'
    [root@node1 Shell]# echo "test1" >> 1.txt 
    [root@node1 Shell]# git add .
    [root@node1 Shell]# git commit -m "add test1"
    [test 0b919fa] add test1
     1 file changed, 1 insertion(+)
    [root@node1 Shell]# git checkout master
    Switched to branch 'master'
    Your branch is ahead of 'origin/master' by 1 commit.
      (use "git push" to publish your local commits)
    [root@node1 Shell]# echo "test2" >> 1.txt 
    [root@node1 Shell]# git add 1.txt 
    [root@node1 Shell]# git commit -m "test2"
    [master fe224bc] test2
     1 file changed, 1 insertion(+)
    [root@node1 Shell]# git merge test
    Auto-merging 1.txt
    CONFLICT (content): Merge conflict in 1.txt
    Automatic merge failed; fix conflicts and then commit the result.
    合并失败:因为现在test分支和master分支同级!
    
    解决:
    [root@node1 Shell]# git status
    # On branch master
    # Your branch is ahead of 'origin/master' by 2 commits.
    #   (use "git push" to publish your local commits)
    #
    # You have unmerged paths.
    #   (fix conflicts and run "git commit")
    #
    # Unmerged paths:
    #   (use "git add <file>..." to mark resolution)
    #
    #   both modified:      1.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@node1 Shell]# cat 1.txt 
    This is dev operation
    hello
    <<<<<<< HEAD
    test2
    =======
    test1
    >>>>>>> test
    修改1.txt冲突的内容,然后再次添加和提交
    [root@node1 Shell]# git add 1.txt 
    [root@node1 Shell]# git commit -m "test12"
    [master deedd5e] test12
    [root@node1 Shell]# cat 1.txt 
    This is dev operation
    hello
    test12
    
    查看分支合并情况:
    [root@node1 Shell]# git log --graph --pretty=oneline --abbrev-commit
    *   deedd5e test12
    |\  
    | * 0b919fa add test1
    * | fe224bc test2
    |/  
    * 1a3e0b5 eagels
    * d55b0d3 add 1.txt file
    * 237e280 Initial commit
    

    Bug分支
    环境:当我们正在dev开发新功能的时候,突然有个紧急bug110需要修复,这是我们就需要将当前dev分支stash,然后假设去修改master分支上的bug,然后就需要切换到master分支创建issue-110,进行修复。

    创建test分支,修改1.txt文件,然后stash将现场快照
    [root@node1 Shell]# git checkout -b test
    Switched to a new branch 'test'
    [root@node1 Shell]# echo "111" > 1.txt 
    [root@node1 Shell]# git stash # 打快照
    Saved working directory and index state WIP on test: 37e752c money
    HEAD is now at 37e752c money
    
    创建issue-111分支,修复bug(修改money.txt)的内容,然后add,commit
    [root@node1 Shell]# git checkout -b issue-111
    Switched to a new branch 'issue-111'
    [root@node1 Shell]# echo "111" > money.txt 
    [root@node1 Shell]# git add money.txt 
    [root@node1 Shell]# git commit -m "change 111"
    [issue-111 3422006] change 111
     1 file changed, 1 insertion(+), 1 deletion(-)
    [root@node1 Shell]# git status
    # On branch issue-111
    nothing to commit, working directory clean
    
    合并分支
    [root@node1 Shell]# git merge issue-111
    
    切换回test分支,恢复快照,继续工作
    [root@node1 Shell]# git checkout test
    Switched to branch 'test'
    [root@node1 Shell]# git status
    # On branch test
    nothing to commit, working directory clean
    [root@node1 Shell]# git stash list
    stash@{0}: WIP on test: 37e752c money
    [root@node1 Shell]# git stash pop # 恢复快照
    # On branch test
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #   modified:   1.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    Dropped refs/stash@{0} (ffbba1442a3a3b6cbda32b7ffa3e131f46b60a38)
    [root@node1 Shell]# cat 1.txt 
    111
    [root@node1 Shell]# git add 1.txt 
    [root@node1 Shell]# git commit -m "change 1.txt"
    [test a6e4e7c] change 1.txt
     1 file changed, 1 insertion(+), 4 deletions(-)
    [root@node1 Shell]# git checkout master
    Switched to branch 'master'
    [root@node1 Shell]# git status 
    # On branch master
    nothing to commit, working directory clean
    
    若要删除一个还未合并的feature分支,可以通过git branch -D <name>强行删除!
    

    多人协作:

    1. 查看远程库信息,使用git remote -v
    2. 本地新建的分支如果不推送到远程,对其他人就是不可见的 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
    3. 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
    4. 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name;
    5. 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

    rebase作用:

    1. rebase操作可以把本地未push的分叉提交历史整理成直线
    2. rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比

    标签管理

    创建标签

    1. 命令git tag <tagname>用于新建一个标签,默认为HEAD,也可以指定一个commit id;
    2. 命令git tag -a <tagname> -m "blablabla..."可以指定标签信息;
    3. 命令git tag可以查看所有标签。

    管理标签

    1. 命令git push origin <tagname>可以推送一个本地标签;
    2. 命令git push origin --tags可以推送全部未推送过的本地标签;
    3. 命令git tag -d <tagname>可以删除一个本地标签;
    4. 命令git push origin :refs/tags/<tagname>可以删除一个远程标签。

    搭建Git服务器

    方案1:

    [root@node2 ~]# yum install git -y
    [root@node2 ~]# adduser git
    [root@node2 git]# mkdir .ssh/
    放入公钥并初始化:
    [root@node2 git]# vim .ssh/authorized_keys
    [root@node2 git]# cd /srv/
    [root@node2 srv]# git init --bare sample.git
    [root@node2 srv]# chown -R git:git sample.git/
    克隆仓库:
    [root@node1 ~]# git clone git@node2:/srv/sample.git
    

    方案2:
    GitLab安装

    环境准备:
    [root@node1 ~]# yum install -y curl policycoreutils-python openssh-server
    [root@node2 ~]# systemctl enable sshd
    [root@node2 ~]# systemctl start sshd
    [root@node2 ~]# firewall-cmd --permanent --add-service=http
    [root@node2 ~]# systemctl reload firewalld
    
    邮箱服务:
    [root@node2 ~]# yum install postfix -y
    [root@node2 ~]# systemctl enable postfix
    [root@node2 ~]# systemctl start postfix
    
    配置YUM源:
    [root@node2 ~]# cat > /etc/yum.repos.d/gitlab_ce.repo << EOF
    > [gitlab-ce]
    > name=Gitlab CE Repository
    > baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
    > gpgcheck=0
    > enabled=1
    > EOF
    [root@node2 ~]# yum makecache
    [root@node2 ~]# yum install gitlab-ce -y
    [root@node2 ~]# sed -i "s/^external_url.*/external_url 'http:\/\/$Host_IP:8090'/g" /etc/gitlab/gitlab.rb
    注意:gitlab本身采用80端口,如安装前服务器有启用80,安装完访问会报错,需更改gitlab的默认端口。
    注意:unicorn本身采用8080端口,如安装前服务器有启用8080,安装完访问会报错,需更改unicorn的默认端口。
    
    每次更改后使配置生效:
    [root@node2 ~]# gitlab-ctl reconfigure
    
    gitlab 日常管理命令:
        gitlab-ctl start
        gitlab-ctl stop
        gitlab-ctl status
        gitlab-ctl restart
        gitlab-ctl reconfigure
    
    最后通过浏览器:http://$Host_IP:8090
    默认root用户,并且重置密码
    

    持续更新ing

    相关文章

      网友评论

        本文标题:Git版本控制系统

        本文链接:https://www.haomeiwen.com/subject/xhswvqtx.html