Git

Published: by Creative Commons Licence

  • Tags:

1.Git基础

git仓库中的.git目录下包含了git的元数据。

1.1.工作区

git工作区是指git仓库中我们自己新建的数据。

1.2.暂存区(stage)

我们可以将工作区新建或修改后的资源利用add命令加入到暂存区。暂存区的信息保存在.git/index文件中。

1.3.对象库

利用commit命令,可以将暂存区的内容写入到对象库中。对象库的信息保存在.git/objects目录下。

1.4.HEAD

在Git中HEAD存储在.git/HEAD文件中。打开HEAD文件我们会发现其中存储了类似如下信息:

ref: refs/heads/master

其指向了.git/refs/heads/master文件,我们继续打开这个文件可以看到如下内容:

0e49fdf6a131da9b7696e0789d91e14f1ade6768

这正是某次提交的SHA-1值。也正是由于这一原因,使得我们可以在大多时候可以以HEAD代替SHA-1作为参数提供给不同的git命令。

HEAD在多数情况下都是指定当前分支最近一次提交的引用。利用git show HEAD可以查看当前HEAD所指向的提交。 HEAD实际上存储了所指向的提交的

1.5.refs

git中每个提交都对应一个SHA-1值。而利用SHA-1值可以在多个命令中引用该次提交。而每次提交的SHA-1值都保存在某个特定的文件中,这个文件在Git中称为references,其保存在.git/refs目录下。

1.6.FETCH_HEAD

每次FETCH操作之后,都会在本地的.git/FETCH_HEAD文件中保存该远程仓库的分支在上一次FETCH时得到的最新版本。

2.Git指令

2.1.init

git init #将当前目录初始化为Git仓库

2.2.status

git status #查看当前仓库状态

2.3.配置用户信息

git config --global user.name #查看当前用户名
git config --global user.name "用户名" #设置用户名
git config --global user.email #查看当前用户邮箱
git config --global user.email "邮箱地址" #设置用户邮箱
git config --global color.ui true #设置git输出带颜色
git config --global http.proxy http://127.0.0.1:1080 #配置HTTP代理(注意无引号)
git config --global https.proxy https://127.0.0.1:1080 #配置HTTPS代理(注意无引号)
git config --global https.proxy socks5://127.0.0.1:1080 #配置socks代理(注意无引号)
git config --global --unset http.proxy #取消HTTP代理
git config --global --unset https.proxy #取消HTTPS代理

用户的配置信息一般存储在.gitconfig文件中。

2.4.add

git add [--all] [--ignore-removal] <file>... #将file添加到暂存区

[–all]用于指定连同工作区删除的内容也要追加,而[–ingore-removal]则指定不提交工作区删除内容。

2.5.diff

git diff 前版本SHA-1值 后版本SHA-1值 #查看后版本相较于前版本的修改
git difftool 前版本SHA-1值 后版本SHA-1值 #利用difftool查看后版本相较于前版本的修改

2.6.log

git log #查看到HEAD为止的提交信息
git log --graph --all #查看分支图

2.7.reset

reset命令用于修改HEAD的值,并允许恢复暂存区和工作区的内容。

git reset [mode] <commit> #将HEAD指向commit

reset的mode接受三个值,其介绍如下:

  • --soft,不修改暂存区和工作区的文件。
  • --mixed,恢复暂存区内容,但是不修改工作区。
  • --hard,恢复暂存区和工作区内容到新HEAD的快照。

2.8.branch

branch命令可以用于显示,创建或删除分支。

git branch #查看当前HEAD所在分支
git branch --list #查看所有本地分支
git branch --list -r #查看所有远程分支
git branch --list -a #查看所有本地分支和远程分支
git branch -m <oldbranch> <newbranch> #将oldbranch分支重命名为newbranch
git branch -d <branch> #删除branch
git branch -d -r <branch> #删除远程分支branch
git push <remote> <:branch> #向远程remote推送对branch的删除操作

2.9.rm

rm命令可以帮助我们从工作区和暂存区中删除某个文件或目录。

git rm -f [-r] <file>... #从工作区和暂存区删除列出的文件
git rm --cached [-r] <file>... #从暂存区删除列出的文件

其中[-r]选项指定如果删除目录,那么将递归删除目录下的所有文件

2.10.checkout

checkout用于从暂存区中读取文件并覆盖到工作区。

git checkout [file]... #从暂存区读取文件并覆盖工作区
git checkout <branch> #切换到branch分支
checkout -b <branch> #创建branch分支后切换到branch分支
checkout -B <branch> #如果branch不存在,则创建。切换到branch分支。

2.11.stash

stash用于隐藏工作区和暂存区的修改,这些信息将被作为补丁保存在本地.git/refs/stash,之后可以应用这些补丁恢复信息。

git stash #隐藏当前工作区和暂存区的修改,并恢复工作区和暂存区到HEAD对应的状态
git stash save [message] #等同于git stash,但是追加额外描述信息
git stash list #列出stash列表,其中包含所有的补丁
git stash show <stash-id> #查看stash补丁的具体信息
git stash apply <stash-id> #应用stash补丁
git stash pop <stash-id> #删除最近的stash补丁并应用
git stash clear #删除所有的stash列表
git stash drop <stash-id> #删除stash补丁

2.12.mv

git mv <source>... <destination directory> #将所有source文件移动到destination directory
git mv <source> <destination> #将source重命名为destination

2.13 revert

revert可以撤销一些现存的提交,并将所有撤销作为一个新提交提交。

git revert [-n] <commit>... #撤销所有指定提交带来的修改
git revert [-n] <from>..<to> #撤销from和to之间的所有提交,包括from和to

[-n]用于指示不生成提交,仅将撤销内容加入到暂存区。这可以帮助你将对个提交的revert作为一个提交提交。

2.14.tag

tag可以为某一次提交增加一个标记。tag保存在refs/tags中。在用到提交的地方都可以用tag来替代。

git tag -a [-m <msg>] [-f] <tagname> <commit> #为提交增加一个tag,附加消息msg,如果-f指定,则会替换现存的同名tag
git tag -l [pattern] #列出所有的tag,如果pattern指定,则列出所有符合pattern的tag
git show <tagname> #显示tag的详细信息
git tag -d <tagname>... #删除所列出的tag
git push <remote> <tagname> #推送tag
git push <remote> --tags #推送本地所有标签
git push <remote> :refs/tags/<tagname> #删除远程标签

2.15.fetch

fetch命令可以用于从其它仓库下载refs和objects信息。

git fetch [--all|repository] [--tags] #从远程库下载
  • --all选项表示选择全部远程库
  • --tags选项表示仅下载tag

2.16.merge

merge用于将多个开发分支合并。

git merge[--ff|--no-ff] [-m <msg>] <branch> #将branch合并到当前分支,创建一个新的提交
  • --ff指定支持fast-forward
  • --no-ff指定不支持fast-forward

2.17.pull

pull用于fetch并于本地分支合并

git pull [--all] [--ff|--no-ff] [<repository>] #等价于git fetch后git merge FETCH_HEAD
git pull --rebase [--all] [--ff|--no-ff] [<repository>] #等价于git fetch后git rebase FETCH_HEAD

2.18.remote

git remote add <name> <url> #增加一个新的远程仓库
git remote rename <old> <new> #将远程仓库old重命名为new
git remote remove <name> #删除远程仓库name

要测试git仓库是否有权限访问,比如git@host:person/repo,可以使用下面的命令:

ssh -v -t git@host:person/repo

如果git仓库是自己搭建的,很可能会选择一个非标准的ssh端口,这样的话,必须显式指定端口port,对于上面的仓库,只需要改造为:ssh://git@host:port/person/repo即可。

2.19.push

将refs提交到远程仓库。

git push [-f] [--all|--mirror|--tags] [<repository>]...  #将本地修改推到远程库
  • --all推送所有分支
  • --prune删除远程分支中在本地没有对应分支的分支
  • -f强制推送,将本地分支覆盖远程分支

2.20.rebase

rebase用于重设当前分支的基,rebase需要选择作为基的分支,之后找到二者的最近的一个交点,交点可以视作当前分支的一个基,之后将这个基转移到新分支的head处。

D--E--F--G master
   \
    A--B--C topic

假设我们现在处于master分支,现在希望重设master的基为topic的head,那么实际效果为:

D--E--A--B--C topic
             \
              F'--G' master
git rebase [-i] <newbase> #将当前分支的基设置为newbase
git rebase [-i] <newbase> <branch> #先执行git checkout <branch>后执行rebase <newbase>

指定-i将允许你在交互模式下选择哪些提交需要被提交。你可以借助这个模式将多个提交合并为一个提交。

2.21.cherry-pick

cherry-pick命令用于将某些提交作为同等数量个新的提交复刻在当前分支上。

D--E--F--G master
   \
    A--B--C topic

之后我们将A,B两个操作复刻到master分支上。首先我们切换到master分支上,之后我们调用cherry-pick命令,结果如下:

D--E--F--G-A'-B' master
   \
    A--B--C topic

下面介绍具体指令:

git cherry-pick [-n] <commit>... #将一个或多个提交复刻到当前HEAD上
  • -n指定不会直接提交,这样我们可以将多个提交合并为一个提交。

2.22 commit

git commit -m "<message>" #将暂存区的内容作为一个commit提交
git commit --amend #修改最近一次提交的备注

Git私仓

Gitlab

gitlab是由GitLab Inc.开发,使用MIT许可证的基于网络的Git仓库管理工具,它由Ruby编写。该仓库非常流行,IBM,Sony,Alibaba等著名都有使用它来管理项目。

安装

使用docker进行安装,使用的image来自于https://github.com/sameersbn/docker-gitlab

Gogs

Gogs是国人开发的一款Git仓库服务。Gogs是使用go开发的,相较于Gitlab更加轻量和简单,而且有着中文文档。

安装

使用docker进行安装,使用的image来自于https://github.com/gogs/gogs/tree/master/docker

配置https

要支持https,首先要安装nginx,并且获得自己的私钥和证书。之后在nginx上开启https协议,并利用nginx的反向代理将https请求以http的形式本地转发给gogs即可。比如我的配置就是

location /gogs/ {
	proxy_pass http://127.0.0.1:9003/;
}

需要注意的是Gogs第一次访问需要通过http协议,在第一次访问时需要设置所需的配置项,这里需要将ROOT_URL配置为nginx的访问入口(因为Gogs会使用这个作为根地址来计算资源文件的URL)。比如我的配置为ROOT_URL=https://127.0.0.1/gogs/