0%

Git部分实践记录

前要

以下包含一些平时经常会用到但容易忘记的操作,或一些有记录价值的操作,但不包含那些更基本的命令或操作,一些较新版本的命令也不记录。部分存在比较官方的文档进行讲解的操作或命令,为了保持文章简短,会给出文档的链接,这里不会再展开。

正式文档

配置全局用户名和邮箱

git的当前用户的主配置文件在(在用户目录的.gitconfig文件)

1
2
git config --global user.name "username"
git config --global user.email "[email protected]"

配置默认编辑器

1
git config --global core.editor vim

提交时自动把所有换行符转换为LF()

1
git config --global core.autocrlf input

配置crlf检查处理

core.safecrlf结合core.autocrlf配置使用,配置为warn出现告警但是仍然允许提交(默认配置),配置为true(直接Fatal拒绝提交),false(不做任何提示,但是仍然会做转换)。

1
git config --global core.safecrlf warn

冗余空白检查

在本地使用git diff等命令的时候将无意义的空白加亮,但是不会做自动修复

1
git config --global core.whitespace "trailing-space,space-before-tab,tab-in-indent,tabwidth=4

生成本机的ssh密钥

生成的密钥在用户目录的.ssh文件夹(包括公钥和私钥),需要在远程git仓库托管服务的配置中添加生成的公钥。

1
2
3
4
5
6
7
8
9
ssh-keygen -t rsa -C "[email protected]"

# 切换至生成路径
# linux环境:cd ~/.ssh
# windows环境:pushd %USERPROFILE%\.ssh

# 公钥文件
# linux环境:~/.ssh/id_rsa.pub
# windows环境:%USERPROFILE%\.ssh\id_rsa.pub

将密码保存到~/.git-credentials

1

解决bash终端中git中文显示乱码的问题

对于windows使用mingw终端可以直接修改终端窗口的配置

1
2
3
Options->Text
Locale修改为zh_CN
Character set修改为UTF-8

直接修改配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 对于配置文件.gitconfig的路径
# linux环境:/etc/gitconfig、~/.gitconfig
# windows环境:%USERPROFILE%\.gitconfig

# 修改
[gui]
# 仓库统一使用utf-8
encoding = utf-8
[i18n]
# log编码使用utf-8
commitencoding = utf-8
[svn]
# 支持中文路径
pathnameencoding = utf-8
[core]
# status引用路径不使用八进制,即允许显示中文
quotepath = false

windows下的图形化git管理工具

windows下推荐使用TortoiseGit

1
https://tortoisegit.org/

建立一个基于CGI脚本生成网页的简易项目查看器

gitweb依赖一个web服务器,这里使用的是lighttpd。在linux环境下会比较方便,但是需要注意一些权限分配的问题。而在windows下需要修改一些仓库下的配置。 ### 几个基本的命令 #### 初始化并启动gitweb

1
git instaweb
#### 启动gitweb
1
git instaweb start
#### 停止gitweb
1
git instaweb stop
### gitweb搭建与配置 #### 1.安装lighttpd
1
2
# 下载与系统对应版本lighttpd,解压到系统上并把lighttpd所在的路径添加到PATH环境变量上
http://lighttpd.dtech.hu/
#### 2.初始化并启动本地仓库的gitweb
1
git instaweb
如果在windows上,这时候去访问gitweb的页面是不正常的,需要修改/.git/gitweb内的配置。

3.修改本地仓库gitweb的配置

所有配置的修改都要在调用完git instaweb之后进行,并且之后要用git instaweb start来启动gitweb,而不能是git instaweb,不然会把修改过的配置重新替换掉。修改前先把lighttpd停止掉,如果git instaweb stop无法停止,直接在任务管理器上结束掉lighttpd。 -/.git/lighttpd.conf -/.git/gitweb_config.perl

4. 修改lighttpd.conf

  • server.document-root
    1
    2
    # 在windows上需要修改为这种形式:"E:/Git/mingw64/share/gitweb"
    server.document-root = "E:/Git/mingw64/share/gitweb"
  • cgi.assign
    1
    2
    # perl所在路径可用where查看
    cgi.assign = ( ".cgi" => "E:/Git/usr/bin/perl.exe" )

5. 修改gitweb_config.perl

  • \(projectroot和\)git_temp
    1
    2
    3
    4
    # - 修改$projectroot和$git_temp要使用以下的路径形式
    # "/E/Project/git-Repository/testdepth"
    our $projectroot = "/E/Project/excelfilter";
    our $git_temp = "/E/Project/excelfilter/.git/gitweb/tmp";

6. 安装CGI.pm模块

这个是perl的CGI支持模块(点击下载),解压到/usr/lib/perl5/vendor_perl下。

7. 启动并访问gitweb

1
2
3
4
git instaweb start

# 默认端口使用的是1234
git web--browse http://127.0.0.1:1234

8.效果预览

gitweb-preview
gitweb-preview

and与unadd操作

add

1
2
3
4
5
6
7
8
9
10
11
12
# 添加所有被修改(modified)和被删除(deleted)的文件,不包括新文件(Untracked files)
git add -u

# 添加当前目录的所有修改,不包含更上级的目录
git add .

# 添加所有变化(包含所有目录),下面两条命令是等同的
git add -A
git add --all

# 交互式add
git add -p

补充遗漏的文件

如果已经commit了,但是还存在遗漏的文件没有add,可以用下面两种方法补充进去(推荐第一种做法)。

  1. commit --amend

    1
    2
    3
    4
    5
    # 1. 首先把遗漏的文件加入暂存区
    git add filename

    # 2. 执行amend,修改完commit message后保存
    git commit --amend

  2. reset --soft

    1
    2
    3
    4
    # 1. 首先reset --soft,如果之前的commit message是有用的最好先复制起来,因为soft模式的reset会撤销提交日志,但是提交的修改会重新放到暂存区中
    git reset --soft head^

    # 2. 重新add文件然后commit

去掉上次提交不应该加进来的文件

1
2
3
4
5
6
7
8
9
# 1. 记录之前的commit message

# 2. 执行soft模式的reset
git reset --soft head^

# 3. unadd文件
git reset filename

# 4. 使用之前记录的commit message重新提交

unadd

清空暂存区并保留工作区

1
2
3
# 下面两条命令是等同的,reset的默认模式就是--mixed(从暂存区删除并保留工作区)
git reset head
git reset --mixed head

撤销特定文件的add操作,把它移出暂存区

1
2
git reset head filename
git reset --mixed head filename

rm操作

把文件从仓库中移除并保留本地文件

1
2
3
4
5
# 文件
git rm --cached filename

# 文件夹
git rm --cached -r folder

把文件从仓库和本地都删除

1
2
3
4
5
# 文件
git rm filename

# 文件夹
git rm -r folder

把文件从所有提交中删除

1
2
# 重写索引,从所有提交中删除指定文件,这常用在把包含敏感信息或版权侵犯的文件删除
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

忽略文件

.gitignore文件

把需要忽略掉的文件的路径/文件名加入.gitignore中(支持正则表达式),关于格式可以参考git Documentation

忽略仓库中特定文件类型的所有文件

1
**/*.exe

忽略已添加入仓库的文件的修改

1
2
3
4
5
# 忽略以添加入库的文件
git update-index --assume-unchanged filename

# 解除忽略
git update-index --no-assume-unchanged filename

commit

自动把原本已加入仓库的文件放到暂存区(add操作)后提交

1
git commit -am "message"

文件修改撤销

==注意:checkout相比reset更加不可逆一些,checkout操作需要慎重,不然原本的修改可能很难找得回来,但是reset会保留或者可以恢复。==

撤销未进入过暂存区的修改,恢复至版本库

状态预览
状态预览
状态预览
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 撤销文件当前的修改,下面两个效果一样
git checkout filename
git checkout -- filename

# 撤销文件夹当前的修改,下面两个效果一样
git checkout folder
git checkout -- folder

# 撤销所有修改,下面两个效果一样
git checkout .
git checkout ./

# 指定版本
git checkout <commit sha1 id> filename
git checkout <commit sha1 id> -- filename

撤销已进入暂存区的修改,恢复至版本库

状态预览
状态预览
状态预览
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 撤销文件当前的修改,下面两个效果一样
git checkout head filename
git checkout head -- filename

# 撤销文件夹当前的修改,下面两个效果一样
git checkout head folder
git checkout head -- folder

# 撤销所有修改,下面两个效果一样
git checkout head .
git checkout head ./

# 指定版本
git checkout <commit sha1 id> filename
git checkout <commit sha1 id> -- filename

当修改已进入暂存区,工作区再次发生修改,恢复到暂存区

状态预览
状态预览
状态预览
1
2
3
4
5
6
7
8
9
10
11
# 撤销文件当前的修改,下面两个效果一样
git checkout filename
git checkout -- filename

# 撤销文件夹当前的修改,下面两个效果一样
git checkout folder
git checkout -- folder

# 撤销所有修改,下面两个效果一样
git checkout .
git checkout ./

当修改已进入暂存区,工作区再次发生修改,恢复到版本区

状态预览
状态预览
状态预览
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 撤销文件当前的修改,下面两个效果一样
git checkout head filename
git checkout head -- filename

# 撤销文件夹当前的修改,下面两个效果一样
git checkout head folder
git checkout head -- folder

# 撤销所有修改,下面两个效果一样
git checkout head .
git checkout head ./

# 指定版本
git checkout <commit sha1 id> filename
git checkout <commit sha1 id> -- filename

强制撤销工作区和暂存区的所有修改

1
git reset --hard head

恢复误删除,原本已加入版本库的文件

1
2
# 指定一个存在该文件的commit sha1 id
git checkout <commit sha1 id> -- filename

关于git checkout误操作的恢复

暂时没有很好的方法,可通过git fsck、git reflog等检查一致性、日志或其他第三方工具的方法来尝试恢复。

版本回退

关于reset的三种模式

  • mixed

保留工作区,并把暂存区(stage)和重置HEAD带来的差异也都放到工作区上,这是reset的默认模式

  • soft

回退到特定版本,只回退commit信息,保留工作目录,并把重置 HEAD 所带来的新的差异放进暂存区(stage)

  • hard

重置暂存区(stage)和工作区

回到文件的特定版本,把当前所有暂时修改都放到工作区,并把两个版本的差异放到暂存区上

1
git reset --soft <commit sha1 id>

回到文件的特定版本,把当前所有暂时修改都放到工作区,也把两个版本的差异放到工作区上

1
2
git reste <commit sha1 id>
git reset --mixed <commit sha1 id>

强制把工作区和暂存区都回退到特定版本

1
git reset --hard <commit sha1 id>

本地状态回退到与远程分支一致

1
git reset --hard origin/master

撤销reset --hard

1
2
3
4
5
# 通过以下命令定位到reset --hard之前的commit id
git reflog

# 使用找到commit id进行reset --hard
git reset --hard <commit sha1 id>

revert

撤销(反做)某个提交

将某个提交进行反向操作然后产生一个revert commit message。

1
git revert <commit sha1 id>

提取文件特定版本的内容(即使文件已经删除)

1
2
git show <commit sha1 id>:<filename>
git show <commit sha1 id>:<filename> > <new-filename>

clone某些仓库时,切换里面的不同版本

1
2
# vX.X.X表示tag名
git checkout vX.X.X

变基(rebase)

整合来自不同分支的修改有两种方法:merge以及rebaserebase即变基,可以理解为修改了分支原本的基底,它会修改新提交的Commit Hash ID,rebase相对使用merge的好处是可以使提交记录更加简洁。

当执行rebase操作时,git会从两个分支的共同祖先开始提取待变基分支上的修改,然后将待变基分支指向基分支的最新提交,最后将刚才提取的修改应用到基分支的最新提交的后面。

延伸阅读:Git分支 - 变基

基本命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 执行变基
git rebase -i <commit sha1 id>

# abort变基
git rebase --abort

# 继续执行变基
git rebase --continue

# rebase的command说明
pick: 无修改
reword: 修改commit message
edit: 会停下来执行amending

squash: 合并后面的提交(注意位置),并合并日志
fixup: 合并后面的提交(注意位置),但是不合并日志

drop: 丢弃提交的内容

exec: 放在最后一行,执行shell命令

merge与rebase的对比

这里直接以例子来看它们之间的区别:

状态预览
状态预览

有两个人在协作开发,都是基于dev分支,从其拉出了feature/hzqfeature/zhonghang分支,它们的基底都是dev分支上的cbbceac这条提交。

现在上图的状况是这样的,feature/hzqfeature/zhonghang分支都各自有两个新的提交,但是feature/hzq已经先feature/zhonghang分支合并到了dev分支上。

而今天刚进入工作,feature/zhonghang分支需要合并dev上的最新改动,然后继续工作,选择有两个,即mergerebase

使用merge

状态预览
状态预览
状态预览
状态预览

对于以上两张图,第一张是在feature/zhonghang,执行git merge dev后的结构,第二张是切到dev分支合并feature/zhonghang后的结构,即执行git merge feature/zhonghang。可以得到以下结论:

  • merge之后基底不变
  • feature/zhonghang分支的两个新提交记录的Commit Hash ID不变,与merge前一样
  • 多出一条新的提交Merge branch 'dev' into feature/zhonghang

使用rebase

状态预览
状态预览
状态预览
状态预览

以上两张图,第一张是在feature/zhonghang,执行git rebase dev后的结构,第二张是切到dev分支合并feature/zhonghang后的结构,即执行git merge feature/zhonghang。可以的到以下结论:

  • rebase之后feature/zhonghang基底变了
  • feature/zhonghang分支的两个新提交记录的Commit Hash ID变了
  • 提交记录相比merge更加清爽简洁

变基的风险

  • rebase会改变原提交的Commit Hash ID,如果执行变基的分支,在此之前后其它副本分支,那么带来的影响将会不可控
  • 执行rebase之后,分支原有的结构细节可能会丢失

执行变基基本原则

  • 如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基
  • 多人协作时,拉取一个被变基然后强制推送的分支,要通知每个人执行再次变基(git pull --rebase
  • 不要对存在副本分支的分支执行rebase,否则在之后合并时会产生不可控的冲突
  • 不要对已经合并到其它分支的本地修改进行变基
  • 不要在预发布分支或正式分支上执行rebase
  • 只允许对未推送与不存在副本分支的分支执行rebase

修改某些提交的commit message

1
2
# 把对应提交的command修改为reword
git rebase -i <target sha1>

对某些提交执行amend操作

1
2
# 把对应提交的command修改为edit
git rebase -i <target sha1>

合并多个提交

1
2
# 把对应提交的command修改为squash(如果不合并日志使用fixup)
git rebase -i <target sha1>

丢弃某些提交的修改

1
2
# 把对应提交的command修改为drop
git rebase -i <target sha1>

pull时执行变基

1
git pull --rebase

diff & patch

diff

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 如果文件未add入暂存区,则对工作区与head提交进行比较
# 如果文件已add入暂存区,则对工作区与暂存区进行比较
git diff
git diff --

# 对暂存区与head进行比较
git diff --staged
git diff --cached

# 与特定版本进行比较
git diff head
git diff head^^
git diff head~2

# 暂存区与特定版本进行比较
git diff head --staged
git diff head^^ --cached
git diff head~2 --cached

# 比较两个提交
git diff <commit sha1 id> <commit sha1 id>

# 比较两个分支
git diff <branch name one> <branch name two>
git diff <branch name one>..<branch name two>

# 如果两个分支是派生关系,获取其中一条分支自子分支创建以来的变化
git diff master...sub-branch # 获取sub-branch的变化
git diff sub-branch...master # 获取master的变化

# 只显示基本的diffstat
git diff --stat

# 只显示存在变化的文件列表
git diff --name-status

# 反向diff
git diff -R

生成patch

1
2
3
4
5
# 模板
git diff > <branch name>-<short commit id>-<desc>.patch

# 需要修改desc
git diff > `git name-rev --name-only head`-`git rev-parse --short head`-<desc>.patch

应用patch

1
2
git apply <branch name>-<short commit id>-<desc>.patch
patch < <branch name>-<short commit id>-<desc>.patch

使用二分法(bisect)定位引入的bug

情景模拟准备

仓库中有一个record.txt文本文件,如果有一行的文本为“有bug”表示存在bug。已知其中一个正常提交的commit id是902c829f42b14d547330519993674e7f909a73a4,引入bug提交的commit id是98068739138d5785f2186d37efdfadfe9b5ebf1d。

名词定义

bad:存在bug的提交

good:无bug的提交

做法1

  1. 开始进入二分法定位bug时需要指定一个已知存在bug(bad)与无bug(good)的提交
  2. 初始化并进入二分操作
    1
    2
    # start后参数为空表示已知的bad和good提交在后续标记
    git bisect start
  3. 标记一个good的提交
    1
    git bisect good 902c829f42b14d547330519993674e7f909a73a4
  4. 标记当前commit存在bug,这时会采用二分法跳到good与bad中间的commit
    1
    git bisect bad
  5. 经过上面标记完成后,二分法定位bug正式开始。到了下一个commit,需要检查该提交是否存在bug,然后完成标记或者跳过该提交
    1
    2
    3
    4
    5
    6
    7
    8
    # 如果当前commit存在bug则标记为bad
    git bisect bad

    # 如果当前commit无bug则标记为good
    git bisect good

    # 跳过该提交则执行skip
    git bisect skip
  6. 执行上面操作之后都会定位到下一个commit,重复操作直到定位到bug,git会给出首次引入bug的commit的提示的
  7. bug定位完成后退出二分查找
    1
    git bisect reset
    ### 做法2
  8. 在初始化时标记一个bad提交和一个good提交
    1
    2
    # git bisect start <bad> <good>
    git bisect start head 902c829f42b14d547330519993674e7f909a73a4
  9. 剩下的做法与做法1相同

做法3(使用图形化)

  1. 初始化
    1
    git bisect start head 902c829f42b14d547330519993674e7f909a73a4
  2. 进入图形化操作
    1
    git bisect visualize

做法4(使用脚本让git自动完成定位)

  1. 编写一个可以检查bug的脚本,脚本返回0表示无bug,返回其它任意值表示存在bug,例如:
    1
    2
    3
    # file: check
    #!/bin/sh
    ! grep -q "有bug" record.txt
  2. 开始执行二分法定位bug
    1
    2
    git bisect start head 902c829f42b14d547330519993674e7f909a73a4
    git bisect run ./check

查看日志

1
git bisect log

暂储(stash)

stash在把当前的修改打包存储起来,然后执行其它操作时会很有用。 ### 基本命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 列出所有stash
git stash list

# 查看stash的变动
git stash show

# 恢复stash
git stash pop
git stash pop stash@{0}

# 恢复并保留暂存
git stash apply stash@{index}

# 删除暂存
git stash drop stash@{index}

# 清空暂存
git stash clear

从stash中创建出新分支

1
2
3
4
5
6
7
8
9
10
11
12
# 做法1:
git stash
git stash branch <new branch name> <stash id>

# example
git stash
git stash branch feature-modify stash@{0}

# 做法2:
git stash
git checkout -b <new branch name>
git stash pop

grep

1
2
3
4
5
6
7
8
# 从仓库中搜索文档
git grep "text"

# 显示匹配的行数
git grep -n "text"

# 显示匹配的数目
git grep -c "text"

获取版本库的某些信息

获取最新提交的commit id

1
2
3
4
5
# 完整的commit id
git rev-parse head

# 短commit id
git rev-parse --short head

获取当前分支名字

1
2
3
4
5
6
7
8
9
10
11
12
# 不受版本限制的方法
git branch | awk '$1 == "*"{print $2}'

git name-rev --name-only head

# git v1.8+
git symbolic-ref --short HEAD

# git v1.7+
git rev-parse --abbrev-ref HEAD

git symbolic-ref HEAD | sed -e "s/^refs\/heads\///"

生成版本号

1
git describe

branch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 拉取所有分支
git fetch --all

# 查看所有分支
git branch -a

# 查看所有远程分支
git branch -r

# 删除远程分支
git push origin --delete <branch name>

# 从远程仓库拉取分支
git fetch origin <branch name>
git fetch origin <branch name>:<local branch name>

# 关联本地分支与远程分支
git branch --set-upstream-to <local branch name> origin/<remote branch name>

worktree

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看所有工作区
git worktree list

# 添加新工作区
git worktree add <new path> -b <new branch> <base branch>

# 锁定工作区
git worktree lock <path>

# 解锁工作区
git worktree unlock <path>

# 删除工作区
git worktree remove <path>

tag部分操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 打tag,这时会提示编辑tag消息,编辑完后保存
# X.X.X为版本号
git tag -a vX.X.X

# 直接指定message
git tag -a vX.X.X -m "message"

# 给历史提交创建tag
git tag -a vX.X.X <commit sha1 id> -m "message"

# 查看tag的相信信息
git show vX.X.X

# 删除本地tag
git tag -d vX.X.X

# 推送tag到远程仓库
git push origin master --tags
git push --tags

# 拉取远程所有tag
git fetch --tags

# 删除远程tag
git push origin master :refs/tags/vX.X.X

remote

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 获取所有remote消息
git remote -v

# 添加新remote名字
git remote add <new name> <url>
git remote add --mirror=push <new name> <url>
git remote add --mirror=fetch <new name> <url>

# 删除remote
git remote remove <name>

# 重命名
git remote rename <old name> <new name>

# 获取remote关联的url
git remote get-url <name>
git remote get-url --push <name>
git remote get-url --all <name

# 给指定remote添加或删除url
git remote set-url --add <name> <new url>
git remote set-url --delete <name> <url>

# 获取远程仓库的所有引用
git ls-remote

log

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看多个分支的log
git log master develop

# 查看多个分支的log并排除某些分支的并集
git log develop ^master

# 如果两个分支是派生关系,获取其中一条分支自子分支创建以来的提交log
git log master...develop

# 查看提交范围的日志
git log 起始..结束
git log --pretty=oneline 75ec652..head

# 只显示一行
git log --pretty=oneline

# 查看文件的历史修改
git log --follow -p filename

reflog

reflog == ref log,查看更多的log,reflog是属于本地的,可设定过期时间

1
2
3
4
git reflog

git log -g
git log --walk-reflogs

whatchanged

1
2
3
4
5
# 查看改动了特定文件的提交
git whatchanged filename

# 查看提交日志改动的文件
git whatchanged

blame

检查某些修改造成的后果应该由谁负责。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 检查文件职责
git blame filename

# 指定特定行数
git blame 3,4 filename
git blame 3,3 filename
git blame 3,+4 filename

# 显示行数
git blame -n filename

# 指定版本
git blame head^ filename

# 指定范围
git blame head^^^.. filename

# 1周前
git blame --since=1.weeks -- filename

# 1天前
git blame --since=1.days -- filename

notes

1
2
3
4
5
6
7
# 给对象添加notes(注释)
git notes edit head
git notes edit c6127b38c1aa25968a88db3940604d41529e4cf5

# 查看对象的notes
git notes show head
git notes show c6127b38c1aa25968a88db3940604d41529e4cf5

objects

查看所有对象

1
find .git/objects -type f

ls-files

1
git ls-files

查看对象的内容

1
2
3
4
5
# 通过show
git show <object>

# 通过cat-file
git cat-file -p <object>

查看树对象

1
2
git show <commit sha1 id>^{tree}
git cat-file -p <commit sha1 id>^{tree}

查看对象的类型

1
git cat-file -t <object>

查看对象的大小

1
git cat-file -s <object>

archive

为仓库创建归档文件,如:.zip、tar.gz等文件。

1
2
3
4
5
6
7
8
9
10
11
# 查看所有支持的格式
git archive -l

# 指定压缩级别参数
-0 ~ -9,指定-0时不进行压缩

# 指定prefix参数
--prefix=<prefix>

# 指定输出路径
-o <path>

例子

1
2
# 为仓库的head创建tar.gz格式的归档文件,不进行压缩,输出到example.tar.gz
git archive --format=tar.gz -o example.tar.gz -0 head

从远端拉取tag然后建立归档

1
git archive --remote=origin --format=tar.gz -o v1.0.tar.gz v1.0

维护相关

var

1
2
# 列出所有git变量
git var -l

clean

1
2
3
# 清理工作区,删除所有未跟踪的文件
git clean
git clean -f

bundle

&esmp;把一些操作打包导出,在其他地方导入,详细参考文档

1
2
3
4
5
# 把指定分支打成bundle
git bundle create <bundle file name> <branch name>

# 提取映射
git fetch <bundle file name> <bundle branch name>:<local branch name>

pack

Git 最初向磁盘中存储对象时所使用的格式被称为“松散(loose)”对象格式。 但是,Git 会时不时地将多个这些对象打包成一个称为“包文件(packfile)”的二进制文件,以节省空间和提高效率。 当版本库中有太多的松散对象,或者你手动执行 git gc 命令,或者你向远程服务器执行推送时,Git 都会这样做。

当文件是悬空(dangling)的时,不会将它们打包进新生成的包文件中。

∗.pack是包文件,∗.idx是索引文件。

详细的说明看文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看所有对象
find .git/objects -type f

# 查看pack的内容
git verify-pack -v .git/objects/pack/pack-<sha1 id>.idx

# 执行垃圾回收与优化本地存储库,打包对象
git gc

# 重新打包
git repack

# 打包head与tag以便高效的存储库访问
git pack-refs --all

# 查找多余的包文件
git pack-redundant --all

# 获取unpacked对象的数目
git count-objects -v

hooks

<repso path>/.git/hooks下面有各种钩子的example,修改脚本内容并把.sample后缀去掉就可以启用钩子了。具体钩子的用处和含义看文档

请我喝瓶肥仔快乐水?

欢迎关注我的其它发布渠道