精通Git

Git基础

获取Git仓库

$ git init

记录每次更新到仓库

git add .
git commit -m 'commit mesg'

查询提交历史

#+END_SRC git log #+END_SRC

撤消操作

git commit --amend

这个命令会将暂存区中的文件提交,如果自上次提交以来你还未做任何修改,那么快照会保持不变,而你所修改的只是提交信息。 e.g.

git commit -m 'initial commit'
git add ofrgotten_file
git commit --amend

最终你只会有一个提交 - 第二冷饮提交将代替第一次提交的结果。

  • 取消暂存的文件

    git reset HEAD
    
  • 撤消对文件的修改

    git checkout xxx.file
    

远程仓库的使用

  • 查看远程仓库

    get remote -v
    
  • 添加远程仓库

    git remote add <shortname> <url>
    
  • 从远程仓库中抓取与拉取

    #+END_SRC git fetch [remote-name] #+END_SRC

  • 推送到远程仓库

    #+END_SRC git push origin master #+END_SRC

  • 查看远程仓库

    git remote show origin
    
  • 远程仓库的重命名

    git remote rename oldname newname
    
  • 远程仓库的移除

    git remote rm remotename
    

标签

  • 列出标签

    git tag
    
    git tag -l 'XXXX*'
    
  • 创建标签

    • 附注标签 -a选项
    git tag -a v1.4 -m 'version 1.4'
    
    git show v1.4
    
    • 轻量标签
    git tag v1.4-lw
    
    • 后期打标签
    git tag -a v1.2 commitId
    
  • 共享标签

    git push origin tagname
    

    如果想一次性推送很多标签可以使用带有–tags

    git push origin --tags
    
  • 检出标签

    git checkout -b [branchname] [tagname]
    

Git别名

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

Git分支

分支简介

  • 分支创建

    git branch branchname
    

    Git通过一个名为HEAD的特殊指针区分当前是在拿一个分支上。可以将HEAD想像成当前分支的别名。可以使用git log命令查看各个分支当前所指的对象。

    git log --oneline --decorate
    
  • 分支切换

    git checkout branchname
    

    切换后HEAD就会指向新的branchname 可以使用git log 查看分叉历史

    git log --oneline --decorate --graph --all
    

分支的新建与合并

git checkout -b branchname

这条命令相当于

git branch branchname
git checkout branchname
  • 将新分支合并到主分支上

    git checkout master   *切换回主分支
    git merge branchname   * merge分支到主分支
    
  • 删除无用分支

    git branch -d branchname
    
  • 遇到冲突时的分支合并

    git mergetool
    

    该命令会为你启动一个合适的可视化合并工具然后

    git add .
    git commit -m 'xxxxx'
    

分支管理

  • 查看分支

    git branch
    

    会列出所有的分支,带*字符的表示当前检出的分支如果想查看每个分支的最后一次提交可以

    git branch -v
    

    –merged与–no-merged这两个选项可以过滤这个列表中或沿示合并到当前分支 的分支。

    git branch --merged
    

    这个列表中不带*号的分支表示已经合并到当前分支了,可以安全删除还可以查看尚未合并到当前分支的分支

    git branch --no-merged
    

    这里显示的分支使用git branch -d删除会失败。因为会丢失信息。不过可以使用git branch -D强制删除

    git branch -D branchname * 强制删除分支
    

分支开发工作流

远程分支

显示获得远程引用的完整列表

git ls-remote
  • 推送

    git push (remote) (branchname)
    

    将branchname推送到remote服务器或

    git push (remote) localbranchname: originbranchname
    
  • 拉取

    将远程指定分支合并到当前所在分支

    git merge origin/branchname
    

    或建立本地分支跟踪远程分支

    git checkout -b localbranchname origin/remotebranchname
    

    git checkout --track origin/remotebranchname
    

    设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支,你可以在任意时间使用-u或者–set-upstream-to 选项运行git branch来显示设置

    git branch -u origin/originbranchname
    

    如果想要查看设置的所有跟踪分支,可以使用git branch的-vv选项。这会将所有的本地分支列出来并且包含更多的信息,如每一个分支正在跟踪哪个远程分支与本地分支是否领先、落后或是都有。

    git branch -vv
    
    • git pull

      git pull = git fetch + get merge

  • 删除远程分支

    git push origin --delete originbranchname
    

变基

在Git中整合来自不同分支的修改主要 有两种方式:merge和rebase

  • rebase

    e.g.

    git checkout experiment
    git rebase master
    

    它的原理是首先找到这两个分支(即当前分支experiment,变基操作的目标基底分支master)的最近共同祖先,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底,最后以此将之前另存为临时文件的修改依序应用。现在回到master分支,进行一次快进合并 #+END_SRC git checkout master git merge experimet #+END_SRC e.g.

    git rebase --onto master server client
    

    将client中的修改合并到主分支并发布,但暂时不合并server中的修改

    git rebase master server
    git checkout master
    git merge server
    

    将server中的修改变基到master上,server中的代码被“续”到了master后面。

服务器上的Git

协议

本地协议,HTTP协议,SSH协议以及Git协议。

  • 本地协议

    本地协议中,无程版本库就是硬盘内的另一个目录,常见于团队每个成员都对一个共享的文件系统拥有访问权。 e.g.

    git clone /opt/git/project.git
    

    git clone file:///opt/git/project.git
    

    增加一个本地版本库到现有的Git项目

    git remote add local_proj /opt/git/project.git
    
    • 优点
      • 简单
    • 缺点
      • 共享文件系统比较难配置,并且比起基本的网络连接访问,不方便从多个位置访问。
  • HTTP协议

    • 智能(Smart)HTTP协议
    • 哑(Dumb)HTTP协议

      • 优点
        • 不同的访问方式只需要一个URL以及服务器只需要授权时提示输入授权信息
        • HTTP/S协议被广泛使用,一般企业防火墙都会允许这些端口的数据通过。
      • 缺点
        • 在一些服务顺上,架设HTTP/S协议的服务端会比SSH协议的棘手一些。
  • SSH协议

    git clone ssh://user@server/project.git
    

    或 scp式写法 #+END_SRCsell git clone user@server:project.git #+END_SRC

    • 优点
      • SSH架设相对简单
      • SSH访问是安全的
      • 与HTTP/S协议、Git协议及本地协议一样,SSH协议很高效,在传输前也会尽量压缩数据。
    • 缺点
      • 你不能通过他实现匿名访问。
  • Git协议

    这是包含在Git里的一个特殊的守护进程;它监听在一个特定的端口(9418),类似于SSH服务,但是访问无需任何授权。

在服务器上搭建Git

  • 将现有的仓库导出为裸仓库–即一个不包含当前工作目录的仓库
git clone --bare my_project my_project.git

现在,你的my_project.git目录中应该有Git目录的副本了。整体上效果大致相当于

cp -Rf my_project/.git my_project.git
  • 把裸仓库放到服务器上

假设服务器git.example.com的服务器已经架设好 ,并可以通过SSH连接,你想把所有的Git仓库放在/opt/git目录下,你可以通过以下命令复制你的裸仓库来创建一个新仓库:

scp -r my_project.git user@git.example.com:/opt/git

此时,其他通过SSH连接这台服务器并对/opt/git目录拥有可读权限的使用者,通过运行以下命令就可以克隆你的仓库。

git clone user@git.example.com:/opt/git/my_project.git

GitLab

可以在http://bitnami.com/stack/gitlab%E4%B8%8A%E8%8E%B7%E5%8F%96%E4%B8%80%E9%94%AE%E5%AE%89%E8%A3%85%E5%8C%85, 同时调整配置使之符合你的特定的环境。