第5章:直接操纵远程

基础知识

每个repo可以引用(注意不是第0章中的“放弃对象和引用的所有权并链接”)其它repo。 这种对repo的引用称为remote。每个remote包括以下信息:

  • 名字,惯例是origin和upstream

  • URL,常见协议包括http、https、ftp、files、ssh(git@github.com实际上是ssh协议)

  • 关于如何进行fetch的信息

本章所有命令都无需worktree。为了方便起见,本章所有命令都将直接在repo中操作,省略--git-dir

git init --bare .
# Initialized empty Git repository in /root/
ls
# HEAD
# branches
# config
# description
# hooks
# info
# objects
# refs

Packfile

研究Git remotes之前需要先研究packfile。 由于packfile内部格式相当复杂,本节不介绍Lv0命令。 以下命令均为Lv2。

在开始之前,先创建几个对象:

检查对象创建情况:

创建Packfile

自动列出应该打包哪些对象

前述方法手工指定了打包的文件;然而,由于没有打包blob 5ff3和tree 2da9,即便接收者拿到了对象也没有什么卵用(还原不出整个tree 187e,在git checkout-index时会失败)。 此时需要祭出Git最复杂的Lv2命令之一:git rev-list (复杂程度与之不相上下的还有git filter-branchgit merge-tree)。

查看Packfile

对于复杂的packfile,可能出现链状结构(只保存了增量修改信息)。详情参见这里

解压缩Packfile

(先删除所有objects:rm -rf objects/*)

跨库直接对象传输

首先创建另一个repo:

直接索要对象(若不加--keep则直接解Packfile):

注意:$(pwd)还可以是URL,用于跨域对象传输

跨库直接引用传输

创建引用:

直接索要引用及其对象:

直接推送引用及其对象:

检查远程引用:

跨库间接传输

跨域但无法建立网络连接时,先创建bundle:

再解bundle:

Lv3命令

首先用Lv0命令修改设置,以讨论设置对Lv3的影响。

指明remote的git pushgit fetch

裸remote:

带默认fetch的remote:

强制全盘push:

未指明remote的git pushgit fetch

使用Lv3命令修改设置

关于git pull

git pull基本上是先git fetchgit merge FETCH_HEADgit pull --rebase基本上是先git fetchgit rebase FETCH_HEAD。 由于这个命令高度不可控,非常不推荐使用。 然而git pull --ff-only却非常有用,是先git fetchgit merge --ff-only FETCH_HEAD

复制repo:git clone

(参见第5章)

git clone --mirror

复制另一个repo的大多数对象、所有普通引用、特殊引用HEAD

  • Lv2

  • Lv3

git clone --bare

--mirror类似,但是四不像(没有config)

  • Lv2

  • Lv3

git clone

  • Lv2

  • Lv3

总结

  • Lv2

    • Packfile

      • git rev-list --objects <object> | git pack-objects <path-prefix>

      • git unpack-objects

    • Bundle

      • git bundle create <file> <refs>*

      • git bundle unbundle <file>

    • 传输

      • git fetch-pack <url> <hash>* - 需要git config uploadpack.allowAnySHA1InWant true

      • git fetch-pack <url> <ref>*

      • git send-pack --force <url> <local-ref>:<remote-ref>*

    • 检查

      • git ls-remote <url>

  • Lv3

    • 配置

      • git remote add <remote> [--mirror=push|fetch] <url>

      • git push -u <remote> <local-ref>:<remote-ref>

    • 传输

      • git push <remote> <local-ref>:<remote-ref>

      • git fetch <remote> <remote-ref>:<local-ref>

    • 一键跟上进度

      • git pull --ff-only

    • 基于远程创建repo

      • git clone --mirror <url> <repo>

      • git clone --bare <url> <repo>

      • git clone [--no-checkout] [--branch <ref>] [--separate-git-dir <repo>] <url> <worktree>

    • 不推荐使用的邪恶命令

      • git pull [--rebase]

最后更新于

这有帮助吗?