跨多个系统使用 Git,无需网络访问

Tut*_*een 86 git

我想使用版本控制,但由于安全原因,我正在使用的服务器无法访问互联网:我只能移动 USB 闪存驱动器上的文件。我还能在这个设置中使用 Git 吗?我可以创建可以应用于 Git 存储库的小补丁吗?

Bob*_*Bob 157

当然,Git 不需要特定的协议。开箱即用的标准客户端支持HTTP(S)、SSH、自定义 Git 协议以及重要的本地协议。这只是需要一个本地.git目录的路径,该路径可以在工作目录 ( /path/to/project/.git) 内或只是一个裸目录 ( /path/to/project.git),尽管命名只是一种约定。

这意味着您当然可以添加闪存驱动器作为遥控器:

git remote add origin /mnt/flashdrive/foo.git
Run Code Online (Sandbox Code Playgroud)

或者,在 Windows 上:

git remote add origin F:\foo.git
Run Code Online (Sandbox Code Playgroud)

或者甚至将其添加为具有不同名称的附加遥控器(如果您更愿意origin指向某处的 Internet 服务器):

git remote add flashdrive /mnt/flashdrive/foo.git
Run Code Online (Sandbox Code Playgroud)

然后你就可以像其他遥控器一样推/拉这个遥控器。

如果您阅读文档,您会注意到还有一个file://行为略有不同的协议。建议使用本地路径,因为这将利用一些额外的优化 - 如果您使用该file://协议,那么 git 将使用一些标准网络组件(与本地磁盘通信),这会更慢。

  • 添加到这个特殊的答案 - 在闪存驱动器上使用“裸”存储库进行调查也可能是值得的。“裸”存储库没有工作树,因此在用作共享“权威点”时可以消除一类潜在问题,这听起来像是 OP 的用例。 (50认同)
  • @LightnessRacesinOrbit 重要的是要注意,裸并不一定意味着权威,它只是在这种情况下有用。例如,它也很有用,因为缺少工作树,它占用的磁盘空间(或带宽)较小。这曾经比现在重要得多,但仍然出现。 (6认同)
  • `file://` 也更灵活一些。它允许您使用本地路径无法使用的某些功能(如浅层克隆)。 (5认同)
  • @LightnessRacesinOrbit - 这是一个非常密集的话题,但是,基本上,git 是分布式的,所以每个人都有自己的历史。A 可以向 B 询问他们的历史版本,但 C 不知道,除非有人告诉他们。拥有一个存储“权威”历史的单一存储库意味着 D 充当历史的交换所。所以,A 告诉 D 关于变化,B 和 C 知道与 D 交谈以保持最新状态,而不是在他们之间做旁道的事情。举个例子,如果 OP 的服务器是 C,而闪存驱动器是 D,它可以确保服务器不会被排除在 A/B 交互之外。 (2认同)

use*_*686 47

在一计算机上,不需要什么特别的。git init在您想要的目录中运行并像往常一样使用 Git。

对于跨台计算机同步存储库,有多种方法。

方法 1a(根本没有网络):您可以在 USB 记忆棒上创建一个“裸存储库”,然后像使用任何其他远程存储库一样推送到它并从中拉出。换句话说,通过本地路径的存储库操作与通过 SSH 或 HTTPS URL 的操作没有任何不同。

  1. 创建一个“远程”存储库:

    $ git init --bare /mnt/Stick/Repositories/Large_Project.git
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在计算机 1 中,将所有内容推送给它:

    $ cd ~/Large_Project
    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git push usb master
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在计算机 2 中,和往常一样。

    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git pull usb
    
    Run Code Online (Sandbox Code Playgroud)

(您也可以直接从 URL 或路径推送/获取/拉取。)

方法1b(内部网络):如果你有一个可以使用SSH的内部服务器,并且如果它安装了Git,你可以像上面一样做,只需使用[user@]host:pathorssh://[user@]host/path语法指定一个SSH地址。

  1. 通过git init --bare <somepath.git>在指定服务器上运行(通过 SSH)来创建“远程”存储库。

  2. 在计算机 1 中,与前面演示的方式相同。

    $ git remote add origin myserver.example.com:Gits/Large_Project.git
    
    Run Code Online (Sandbox Code Playgroud)

    或者,如果您更喜欢:

    $ git remote add origin ssh://myserver.example.com/Gits/Large_Project.git
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在计算机 2 中,再次与方法 1a 相同。


方法 2:您可以创建“传输包”,将给定的提交列表归档到单个文件中。

不幸的是,捆绑命令不会自动记住上次捆绑的内容,因此需要手动标记或记笔记。我将仅从 git-bundle 手册中获取示例。

  1. 在计算机 1 中,创建一个包含整个分支的包:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle master
    $ git tag -f last-bundled master
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在计算机 2 中,从包中提取,就像它是一个存储库一样:

    $ cd ~/Large_Project
    $ git pull /mnt/Stick/Project.bundle
    
    Run Code Online (Sandbox Code Playgroud)

后续的 bundle 不需要打包整个master——他们可以只打包新添加的提交last-bundled..master

  1. 在计算机 1 中,创建一个新添加的提交包:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle last-bundled..master
    $ git tag -f last-bundled master
    
    Run Code Online (Sandbox Code Playgroud)
  2. 和上面一样。


Vi.*_*Vi. 20

git bundle create

其中一种方法是使用外部存储在存储库之间交换数据是git bundle。这样,您每次传输只有单个文件,而不是中间 Git 存储库。

每个“git push”都会变成一个文件的创建,“git fetch”从该文件中获取内容。

演示会话

创建第一个存储库并进行第一次“推送”

gitbundletest$ mkdir repo1

gitbundletest$ cd repo1

repo1$ git init
Initialized empty Git repository in /tmp/gitbundletest/repo1/.git/
repo1$ echo 1 > 1 && git add 1 && git commit -m 1
[master (root-commit) c8b9ff9] 1
 1 file changed, 1 insertion(+)
 create mode 100644 1

repo1$ git bundle create /tmp/1.bundle master HEAD
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 384 bytes | 384.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
Run Code Online (Sandbox Code Playgroud)

“克隆”到第二个存储库(即第二台计算机):

gitbundletest$ git clone /tmp/1.bundle repo2
Cloning into 'repo2'...
Receiving objects: 100% (3/3), done.

gitbundletest$ cd repo2/

repo2$ cat 1
1
Run Code Online (Sandbox Code Playgroud)

做一些更改并将它们“推送”到另一个包文件:

repo2$ echo 2 > 1 && git add 1 && git commit -m 2
[master 250d387] 2
 1 file changed, 1 insertion(+), 1 deletion(-)

repo2$ git bundle create /tmp/2.bundle origin/master..master origin/HEAD..HEAD
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 415 bytes | 415.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
Run Code Online (Sandbox Code Playgroud)

“拉取”对第一个存储库的更改:

repo2$ cd ../repo1

repo1$ git pull /tmp/2.bundle 
Receiving objects: 100% (3/3), done.
From /tmp/2.bundle
 * branch            HEAD       -> FETCH_HEAD
Updating c8b9ff9..250d387
Fast-forward
 1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

repo1$ cat 1
2
Run Code Online (Sandbox Code Playgroud)

与第一个包不同,第二个包只包含部分 Git 历史记录,不能直接克隆:

repo1$ cd ..

gitbundletest$ git clone /tmp/2.bundle repo3
Cloning into 'repo3'...
error: Repository lacks these prerequisite commits:
error: c8b9ff94942039469fa1937f6d38d85e0e39893a 
fatal: bad object 250d38747656401e15eca289a27024c61e63ed68
fatal: remote did not send all necessary objects
Run Code Online (Sandbox Code Playgroud)

使用 bundle 的缺点是您需要手动指定每个 bundle 应包含的提交范围。与git push,git bundle不跟踪先前捆绑包中的内容,您需要手动调整refs/remotes/origin/master或捆绑包会比它可能更大。


ken*_*orb 7

您需要先安装Git。然后要创建一个新的存储库,请在您复制的文件夹中运行:

git init
Run Code Online (Sandbox Code Playgroud)

然后,您可以添加要进行版本控制的文件git add-a为所有文件添加)并开始提交更改 ( git commit)。

您不必推送到任何远程,因为您可以处理本地历史记录 ( git log)。

有关更多信息,请检查:


没有互联网的推/拉

使用git push命令,可以通过 SSH 推送(使用本地连接,内网):

git remote add server ssh://[user@]host.xz[:port]/path/to/dev/repo.git/
git push server
Run Code Online (Sandbox Code Playgroud)

或推入文件夹:

git push /mnt/usb/my_repo
Run Code Online (Sandbox Code Playgroud)

这假设您有两个存储库副本。

与拉动相同,例如

git pull /mnt/usb/my_repo
Run Code Online (Sandbox Code Playgroud)

打补丁

要应用补丁,您可以使用patchcommand 或git apply.

请参阅:从 git 存储库创建补丁或差异文件并将其应用到另一个不同的 git 存储库


小智 4

您也可以在本地使用 Git。然后,您的提交仅存储在本地,并且您仍然可以对其进行版本控制(并且可以比较/合并等),但您无法从任何其他计算机访问存储库。

git init您可以通过在本地文件夹中运行来启动本地 Git 存储库。正如这里所描述的

  • 我知道,但我想在另一台计算机上工作并将其应用于无法访问互联网的服务器上的文件 (3认同)
  • @TutuKaeen 我认为将存储库放在闪存驱动器上并将其克隆/同步到不同计算机的硬盘驱动器没有任何问题。然而,“无法访问互联网的服务器”听起来很奇怪,服务器的目标是提供服务,大多数情况下该服务与网络相关(但并非总是如此)。 (2认同)
  • @dhae - 请花点时间提供有关如何在本地使用 Git 的更多详细信息。仅表明可以完成并没有多大帮助。 (2认同)
  • @anonymousLurker 该服务正在向非常重要的机构中的封闭网络提供数据。它对广泛的互联网没有任何服务,因为数据非常脆弱并且仅供员工使用。 (2认同)