我想使用版本控制,但是由于安全原因,我正在使用的服务器无法访问互联网:我只能在USB闪存驱动器上移动文件。我仍然可以在此设置中使用Git吗?我可以创建可应用于Git存储库的小补丁吗?
server
对于未连接任何网络的机器使用该术语似乎很奇怪。即使没有互联网,它也可能只是一个本地网络,但它仍然是一个网络。
我想使用版本控制,但是由于安全原因,我正在使用的服务器无法访问互联网:我只能在USB闪存驱动器上移动文件。我仍然可以在此设置中使用Git吗?我可以创建可应用于Git存储库的小补丁吗?
server
对于未连接任何网络的机器使用该术语似乎很奇怪。即使没有互联网,它也可能只是一个本地网络,但它仍然是一个网络。
Answers:
当然,关于Git的任何事情都不需要特定的协议。刚刚开箱的标准客户端支持 HTTP(S),SSH,自定义Git协议和,重要的是,当地的协议。尽管命名只是一个约定,但这只需要指向本地.git
目录的路径,该目录可以位于工作目录(/path/to/project/.git
)内,也可以位于裸目录(/path/to/project.git
)内。
当然,这意味着您可以将闪存驱动器添加为遥控器:
git remote add origin /mnt/flashdrive/foo.git
或者,在Windows上:
git remote add origin F:\foo.git
甚至将其添加为其他名称的远程(如果您希望origin
指向某处的Internet服务器):
git remote add flashdrive /mnt/flashdrive/foo.git
然后,您就可以像其他遥控器一样将其推入/拉出遥控器。
如果您阅读了文档,您会发现还有一个file://
协议的行为略有不同。建议使用本地路径,因为这将利用一些其他优化方法-如果您使用file://
协议,则git将使用一些标准的网络组件(与本地磁盘通信),这比较慢。
file://
也更灵活一点。它允许您使用本地路径无法使用的某些功能(例如浅克隆)。
在单台计算机上,不需要任何特殊设置。git init
在您需要的目录中运行,并像往常一样使用Git。
为了在多台计算机之间同步存储库,有几种方法。
方法1a(根本没有网络):您可以在USB记忆棒上创建一个“裸存储库”,然后将其推入并从中拉出,就像使用其他远程存储库一样。换句话说,通过本地路径进行的存储库操作与通过SSH或HTTPS URL进行的操作没有什么不同。
创建一个“远程”存储库:
$ git init --bare /mnt/Stick/Repositories/Large_Project.git
在计算机1中,将所有内容推送到其中:
$ cd ~/Large_Project
$ git remote add usb /mnt/Stick/Repositories/Large_Project.git
$ git push usb master
在计算机2中,一如既往。
$ git remote add usb /mnt/Stick/Repositories/Large_Project.git
$ git pull usb
(您也可以直接从URL或路径推/获取/拉。)
方法1b(内部网络):如果您的内部服务器具有SSH,并且安装了Git,则可以执行上述操作,只需使用[user@]host:path
或ssh://[user@]host/path
语法指定SSH地址即可。
通过git init --bare <somepath.git>
在指定服务器上运行(通过SSH)来创建“远程”存储库。
在计算机1中,方法与前面演示的相同。
$ git remote add origin myserver.example.com:Gits/Large_Project.git
或者,如果您喜欢:
$ git remote add origin ssh://myserver.example.com/Gits/Large_Project.git
在计算机2中,再次与方法1a相同。
方法2:您可以创建“传输捆绑包”,将给定的提交列表存档到单个文件中。
不幸的是,bundle命令不能自动记住上次已捆绑的内容,因此需要手动标记或记笔记。我将仅从git-bundle手册中获取示例。
在计算机1中,创建整个分支的捆绑包:
$ cd ~/Large_Project
$ git bundle create /mnt/Stick/Project.bundle master
$ git tag -f last-bundled master
在计算机2中,将其作为存储库从捆绑软件中拉出:
$ cd ~/Large_Project
$ git pull /mnt/Stick/Project.bundle
随后的捆绑包不需要打包整个master
包,last-bundled..master
而是可以打包来自其中的新添加的提交。
在计算机1中,创建一包新添加的提交:
$ cd ~/Large_Project
$ git bundle create /mnt/Stick/Project.bundle last-bundled..master
$ git tag -f last-bundled master
同上。
manual tagging or note-keeping is needed
,除非回购协议非常庞大,否则一种选择是:git bundle create my.bundle --all
,其中应包含所有内容
.git/
隐藏文件夹中找到),而没有“工作树”(可编辑文件)。这是您git push
要使用的存储库的首选形式。
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)
“克隆”到第二个存储库(即第二台计算机):
gitbundletest$ git clone /tmp/1.bundle repo2
Cloning into 'repo2'...
Receiving objects: 100% (3/3), done.
gitbundletest$ cd repo2/
repo2$ cat 1
1
进行一些更改,然后将其“推”到另一个捆绑文件中:
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)
“拉”对第一个存储库的更改:
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
与第一个捆绑包不同,第二个捆绑包仅包含部分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
使用捆绑软件有一个缺点,您需要手动指定每个捆绑软件应包含的提交范围。与不同的是git push
,git bundle
它不会跟踪先前捆绑软件中的内容,因此您需要手动进行调整,refs/remotes/origin/master
否则捆绑软件会变得更大。
--all
标志以获取所有内容。如果仓库足够小,这是最简单的过程,因为您每次都只需传输所有内容!只是不要松开记忆棒-可能是最大的安全问题!
您需要先安装Git。然后,要创建新的存储库,请在复制的文件夹中运行:
git init
然后,您可以添加要进行版本控制的文件git add
(-a
为所有文件添加),然后开始提交更改(git commit
)。
您无需推送到任何远程设备,因为您可以处理本地历史记录(git log
)。
有关更多信息,请检查:
使用git push
命令,可以推送SSH(使用本地连接,Intranet):
git remote add server ssh://[user@]host.xz[:port]/path/to/dev/repo.git/
git push server
或推入文件夹:
git push /mnt/usb/my_repo
假设您有存储库的两个副本。
拉动也一样,例如
git pull /mnt/usb/my_repo
要应用补丁,您可以使用patch
command或git apply
。
您也可以在本地使用Git。然后,您的提交仅存储在本地,并且仍具有版本控制(并且可以进行diff /合并等),但是您无法从任何其他计算机访问存储库。
您可以通过git init
在本地文件夹中运行来启动本地Git存储库。如此处所述。