美文网首页
Git常用命令

Git常用命令

作者: d8893ea8ba05 | 来源:发表于2019-06-28 14:55 被阅读0次

    配置及帮助相关

    设置配置:git config --global user.name "John Doe"
    查看配置及出处:git config --show-origin rerere.autoUpdate
    查看帮助:git help <verb>

    基本命令

    将目录初始化为git目录:git init
    克隆已有的项目:git clone https://github.com/libgit2/libgit2 mylibgit
    查看文件状态:git status -s
    移除文件:git rm (-f参数强制移除被修改的文件,如果文件被修改了,默认是不会被移除的)
    取消文件跟踪:git rm --cached
    移动文件:git mv file_from file_to
    查看历史:git log (-p:显示差异;-2:最近两次记录;--stat:文件状态)
    自定义格式历史记录及合并路径:git log --pretty=format:"%h - %an, %ar : %s" --graph
    从标记中回退:git reset HEAD <file>
    退回到上次提交的版本:git checkout -- <file>
    查看远端:git remote -v
    添加远端:git remote add <shortname> <url>
    拉取数据:git fetch/git pull
    推送数据:git push <remote> <branch>
    查看本地与远端分支对应情况:git remote show origin
    重命名/删除远端:git remote rename pb paul / git remote remove paul
    查看/查找tag:git tag/git tag -l "v1.8.5*"
    创建匿名tag:git tag -a v1.4 -m "my version 1.4"
    补打tag:git tag -a v1.2 9fceb02
    推送tag:git push origin v1.5/git push origin --tags
    删除本地/远端tag:git tag -d <tagname>/git push origin --delete <tagname>
    牵出tag:git checkout 2.0.0
    基于tag创建分支:git checkout -b version2 v2.0.0

    分支

    git commit记录与blob.png

    创建分支:git branch testing
    切换分支:git checkout testing
    创建并切换分支:git checkout -b <newbranchname>
    合并分支:git merge hotfix
    删除分支:git branch -d hotfix
    查看分支:git branch (-v:显示最后commit,--merged/--no-merged:过滤已经合并/未合并到当前分支的分支,git branch --no-merged master:是否合并到master的分支)
    同步到远程分支:git push <remote> <branch> (git push origin serverfix 等效于 git push origin refs/heads/serverfix:refs/heads/serverfix)
    创建本地分支并跟踪对应的远程分支:git checkout -b <branch> <remote>/<branch> / git checkout --track origin/serverfix / git checkout <branch>
    设置本地分支的跟踪远程分支:git branch -u origin/serverfix
    显示本地分支与远程分支的对应情况:git branch -vv
    更新本地git数据:git fetch --all
    更新本地git数据并合并当前分支:git pull
    删除远端分支:git push origin --delete <branch>
    变基:git rebase <branch>
    取出client分支,找出处于client(client是基于server开出的分支)分支和server分支的共同祖先之后的修改,然后把她们在master分支上重新放一遍: git rebase --onto master server client
    变基远端:git pull --rebase

    Git服务器

    克隆裸仓库:git clone --bare my_project my_project.git
    将裸仓库放置到服务器上:scp -r my_project.git user@git.example.com:/srv/git
    通过git将仓库目录的组权限设置为可写:git init --bare --shared
    SSH Key目录:cd ~/.ssh
    创建sshkey:ssh-keygen -o
    打印sshkey公钥:cat ~/.ssh/id_rsa.pub
    创建git用户和对应的.ssh目录

      $ sudo adduser git
      $ su git
      $ cd
      $ mkdir .ssh && chmod 700 .ssh
      $ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
    

    添加用户公钥:cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
    创建并初始化git:

      $ cd /srv/git
      $ mkdir project.git
      $ cd project.git
      $ git init --bare
    

    已经设置了git用户和git仓库的服务器,快速添加新项目:

      $ cd myproject
      $ git init
      $ git add .
      $ git commit -m 'initial commit'
      $ git remote add origin git@gitserver:/srv/git/project.git
      $ git push origin master
    

    限制git用户活动在与git相关范围内:

      $ cat /etc/shells   # see if `git-shell` is already in there.  If not...
      $ which git-shell   # make sure git-shell is installed on your system.
      $ sudo -e /etc/shells  # and add the path to git-shell from last command
      $ sudo chsh git -s $(which git-shell)
    

    分布式Git

    生成patch:git format-patch -M origin/master
    应用patch:git am 0001-limit-log-function.patch
    查看不在master上的commit:git log contrib --not master
    查看当前分支与目标分支自从公共基点后的commit:git diff master...contrib
    查看共同父commit:git merge-base contrib master
    展示修改:git diff
    只合并特定节点:git cherry-pick e43a6
    准备发布:git archive master --prefix='project/' | gzip > git describe master.tar.gz / git archive master --prefix='project/' --format=zip > git describe master.zip
    查看远端所有分支,包括pull request:git ls-remote https://github.com/schacon/blink

    Git工具

    查看单个提交:

      $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
      $ git show 1c002dd4b536e7479f
      $ git show 1c002d
    

    选择父节点:HEAD^
    experiment上有但master上没有的提交:git log master..experiment
    refA或refB上有但是refC上没有的提交:git log refA refB ^refC / git log refA refB --not refC
    显示master或者experiment中包含但不是两者共有的提交:git log --left-right master...experiment
    交互式暂存:git add -i
    暂存工作:git stash / git stash push -m
    删除暂存:git stash drop
    应用并删除暂存:git stash pop
    查看所有暂存:git stash list
    暂存并不重置工作区:git stash --keep-index
    同时暂存未跟踪的文件:git stash -u
    清理工作目录:git clean -f -d
    查找某个常量何时引入:git log -S ZLIB_BUF_MAX --oneline
    查找zlib.c文件中git_deflate_bound in the函数的每一次变更:git log -L :git_deflate_bound:zlib.c
    修改最后一次提交:git commit --amend
    修改前三个父节点的提交:git rebase -i HEAD~3
    仅移动HEAD:git reset --soft
    移动HEAD及索引:git reset --mixed (默认)
    移动HEAD并更新目录:git reset --hard
    squash提交

    git reset --soft HEAD~2
    git commit
    

    回退记录:git revert -m 1 HEAD
    假合并:git merge -s ours mundo
    查找bug引入源:git blame -L 69,82 Makefile
    查看代码原来在哪里:git blame -C -L 141,153 GITPackUpload.m
    二分查找:

      $ git bisect start
      $ git bisect bad
      $ git bisect good v1.0
    

    打包分支:git bundle create repo.bundle HEAD master
    克隆打包:git clone repo.bundle repo
    打包commit:git bundle create commits.bundle master ^9a466c5
    验证包:git bundle verify ../commits.bundle
    查看包分支:git bundle list-heads ../commits.bundle
    导入包内容:git fetch ../commits.bundle master:other-master

    自定义Git

    查看git支持的选项列表:man git-config

    Git内部远离

    .git目录下的核心内容:HEAD 文件、(尚待创建的)index 文件,和 objects 目录、refs 目录。objects 目录存储所有数据内容;refs 目录存储指向数据(分支)的提交对象的指针;HEAD 文件指示目前被检出的分支;index 文件保存暂存区信息

    数据对象

    Git的数据对象有四种:blob文件对象、tree树对象、commit提交对象和tag标签对象

    文件对象

    创建新文件并存储入数据内容数据库:

    $ echo 'version 1' > test.txt
    $ git hash-object -w test.txt
    

    接着,向文件里写入新内容,并再次将其存入数据库:

    $ echo 'version 2' > test.txt
    $ git hash-object -w test.txt
    1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
    

    可以查看到不同的版本内容被记录下来:

    $ find .git/objects -type f
    .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
    .git/objects/83/baae61804e65cc73a7201a7252750c76066a30
    

    现在可以把文件内容恢复到某个版本:

    $ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt
    $ cat test.txt
    version 1
    $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt
    $ cat test.txt
    version 2
    

    树对象

    一个树对象包含了一条或多条树对象记录(tree entry),每条记录含有一个指向数据对象或者子树对象的 SHA-1 指针,以及相应的模式、类型、文件名信息:

    $ git cat-file -p master^{tree}
    100644 blob a906cb2a4a904a152e80877d4088654daad0c859      README
    100644 blob 8f94139338f9404f26296befa88755fc2598c289      Rakefile
    040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0      lib
    $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
    100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b      simplegit.rb
    

    为创建一个树对象,首先需要通过暂存一些文件来创建一个暂存区

    git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt
    

    将暂存取写入树对象

    $ git write-tree
    d8329fc1cc938780ffdd9f94e0d364e0ea74f579
    $ git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
    100644 blob 83baae61804e65cc73a7201a7252750c76066a30      test.txt
    

    提交对象

    提交对象包含了一个顶层树对象,代表当前项目快照:

    $ echo 'first commit' | git commit-tree d8329f
    fdf4fc3344e67ab068f836878b6c4951e3b15f3d
    $ git cat-file -p fdf4fc3
    tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
    author Scott Chacon <schacon@gmail.com> 1243040974 -0700
    committer Scott Chacon <schacon@gmail.com> 1243040974 -0700
    
    first commit
    

    创建另外两个提交对象,格子饮用上一个提交:

    $ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3
    cac0cab538b970a37ea1e769cbbde608743bc96d
    $ echo 'third commit'  | git commit-tree 3c4e9c -p cac0cab
    1a410efbd13591db07496601ebc7a059dd55cfe9
    

    这就是每次我们运行 git add 和 git commit 命令时, Git 所做的实质工作——将被改写的文件保存为数据对象,更新暂存区,记录树对象,最后创建一个指明了顶层树对象和父提交的提交对象。 这三种主要的 Git 对象——数据对象、树对象、提交对象——最初均以单独文件的形式保存在 .git/objects 目录下

    标签对象

    标签对象通常指向一个提交对象,而不是一个树对象。 它像是一个永不移动的分支引用——永远指向同一个提交对象,只不过给这个提交对象加上一个更友好的名字罢了。可以像这样创建一个轻量标签:

    $ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
    

    若要创建一个附注标签,Git 会创建一个标签对象,并记录一个引用来指向该标签对象,而不是直接指向提交对象。 可以通过创建一个附注标签来验证这个过程(-a 选项指定了要创建的是一个附注标签):

    $ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'
    $ cat .git/refs/tags/v1.1
    9585191f37f7b0fb9444f35a9bf50de191beadc2
    $ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
    object 1a410efbd13591db07496601ebc7a059dd55cfe9
    type commit
    tag v1.1
    tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700
    
    test tag
    

    refs引用

    引用是一个文件来保存 SHA-1 值,并给文件起一个简单的名字,然后用这个名字指针来替代原始的 SHA-1 值。

    git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
    

    这基本就是Git分支的本质,一个指向某一系列提交之首的指针或引用:

    git update-ref refs/heads/test cac0ca
    

    HEAD

    HEAD 文件是一个符号引用(symbolic reference),指向目前所在的分支。 所谓符号引用,意味着它并不像普通引用那样包含一个 SHA-1 值——它是一个指向其他引用的指针。当我们执行 git commit 时,该命令会创建一个提交对象,并用 HEAD 文件中那个引用所指向的 SHA-1 值设置其父提交字段

    $ cat .git/HEAD
    ref: refs/heads/master
    $ git symbolic-ref HEAD
    refs/heads/master
    $ git symbolic-ref HEAD refs/heads/test
    $ cat .git/HEAD
    ref: refs/heads/test
    

    Git包文件

    Git 最初向磁盘中存储对象时所使用的格式被称为“松散(loose)”对象格式。 但是,Git 会时不时地将多个这些对象打包成一个称为“包文件(packfile)”的二进制文件,以节省空间和提高效率。 当版本库中有太多的松散对象,或者你手动执行 git gc 命令,或者你向远程服务器执行推送时,Git 都会这样做。Git 打包对象时,会查找命名及大小相近的文件,并只保存文件不同版本之间的差异内容。 你可以查看包文件,观察它是如何节省空间的。 git verify-pack 这个底层命令可以让你查看已打包的内容。

    引用规格

    引用规格的格式由一个可选的 + 号和紧随其后的 <src>:<dst> 组成,其中 <src> 是一个模式(pattern),代表远程版本库中的引用;<dst> 是那些远程引用在本地所对应的位置。 + 号告诉 Git 即使在不能快进的情况下也要(强制)更新引用。可在.git/config文件中配置:

    [remote "origin"]
    url = https://github.com/schacon/simplegit-progit
    fetch = +refs/heads/*:refs/remotes/origin/* 
    push = refs/heads/master:refs/heads/qa/master
    

    数据恢复

    reset后找回丢失的commit,并基于丢失的提交创建分支

    git reflog
    git branch recover-branch ab1afef
    

    找回丢失的分支

    git fsck --full
    

    git库删除大的文件记录

    //查找最大的文件
    git verify-pack -v .git/objects/pack/pack-29…69.idx \
      | sort -k 3 -n \
      | tail -3
    
    //显示blob对应的文件
    $ git rev-list --objects --all | grep 82c99a3
    82c99a3e86bb1267b236a4b6eff7868d97489af1 git.tgz
    
    //查找包含这个blob的commit
    git log --oneline --branches -- git.tgz
    
    //重写commit,从某个提交之后的所有commit中删除对应的blob
    git filter-branch --index-filter \
      'git rm --ignore-unmatch --cached git.tgz' -- --all
    
    rm -Rf .git/refs/original
    rm -Rf .git/logs/
    git gc
    //移除不可引用的blob
    git prune
    

    相关文章

      网友评论

          本文标题:Git常用命令

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