I want to use version control but, due to security reasons, the server I'm working on has no internet access: I can only move files on a USB flash drive. Can I still use Git with this setup? Can I create small patches that I can apply on a Git repository?
Sure, there's nothing about Git that requires a particular protocol. Just out of the box the standard client supports HTTP(S), SSH, the custom Git protocol and, importantly, the local protocol. That just takes a path to a local
.git directory, which can be within working directory (
/path/to/project/.git) or just a bare directory (
/path/to/project.git), though the naming is just a convention.
This means you can, of course, add a flash drive as a remote:
git remote add origin /mnt/flashdrive/foo.git
or, on Windows:
git remote add origin F:\foo.git
Or even add it as an additional remote with a different name (if you prefer
origin to point towards an Internet server somewhere):
git remote add flashdrive /mnt/flashdrive/foo.git
Then you can just push/pull to/from this remote just like any other.
If you read the documentation, you'll notice there's also a
file:// protocol that behaves slightly differently. It is recommended to use a local path as that will make use of some additional optimisations - if you use the
file:// protocol then git will use some standard network components (to talk to the local disk), which is slower.
On a single computer, nothing special is needed. Run
git init in your desired directory and work with Git as you normally would.
For synchronizing a repository across multiple computers, there are several methods.
Method 1a (no network at all): You can create a 'bare repository' on the USB stick, then push to it and pull from it as you would with any other remote repository. In other words, repository operations via local paths aren't any different from operations via SSH or HTTPS URLs.
Create a 'remote' repository:
$ git init --bare /mnt/Stick/Repositories/Large_Project.git
In computer 1, push everything to it:
$ cd ~/Large_Project $ git remote add usb /mnt/Stick/Repositories/Large_Project.git $ git push usb master
In computer 2, well, same as always.
$ git remote add usb /mnt/Stick/Repositories/Large_Project.git $ git pull usb
(You can push/fetch/pull from a URL or path directly, too.)
Method 1b (internal network): If you have an internal server with SSH available, and if it has Git installed, you can do the same as above, just specify an SSH address using the
Create a 'remote' repository by running
git init --bare <somepath.git>on the designated server (via SSH).
In computer 1, the same way as demonstrated earlier.
$ git remote add origin myserver.example.com:Gits/Large_Project.git
Or if you prefer:
$ git remote add origin ssh://myserver.example.com/~/Gits/Large_Project.git
In computer 2, again the same as method 1a.
Method 2: You can create 'transfer bundles' which archive a given list of commits into a single file.
Unfortunately the bundle commands don't automatically remember what was already bundled the last time, so manual tagging or note-keeping is needed. I'll just take the examples from the git-bundle manual.
In computer 1, create a bundle of the entire branch:
$ cd ~/Large_Project $ git bundle create /mnt/Stick/Project.bundle master $ git tag -f last-bundled master
In computer 2, pull from the bundle as if it were a repository:
$ cd ~/Large_Project $ git pull /mnt/Stick/Project.bundle
Subsequent bundles don't need to pack the whole
master – they can pack just the newly added commits from
In computer 1, create a bundle of the newly added commits:
$ cd ~/Large_Project $ git bundle create /mnt/Stick/Project.bundle last-bundled..master $ git tag -f last-bundled master
Same as above.
git bundle create
One of the methods is to use external storage to exchange data between repositories is git bundle. This way you only have single files for each transfer, not intermediate Git repositories.
Each "git push" turns into creation of a file, "git fetch" fetches things from that file.
Creating the first repository and doing the first "push"
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)
"cloning" to the second repository (i.e. the second computer):
gitbundletest$ git clone /tmp/1.bundle repo2 Cloning into 'repo2'... Receiving objects: 100% (3/3), done. gitbundletest$ cd repo2/ repo2$ cat 1 1
Doing some changes and "pushing" them to another bundle file:
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)
"pulling" changes to the first repository:
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
Unlike the first bundle, second one contains only partial Git history and is not directly clonable:
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
There is disadvantage in using bundles that you need to manually specify what range of commits each bundle should contain. Unlike
git bundle does not keep track what was in previous bundle, you need to manually adjust
refs/remotes/origin/master or bundles would be bigger than it could be.
You need to first install Git. Then to create a new repository, run within the folder that you've copied:
Then you can add files you want to version control by
git add (add
-a for all files) and start committing the changes (
You don't have to push to any remote, as you can work on your local history (
For more information, check:
Pushing/pulling without internet
git push command, it's possible to push over SSH (using local connection, intranet):
git remote add server ssh://[user@]host.xz[:port]/path/to/dev/repo.git/ git push server
or pushing into the folder:
git push /mnt/usb/my_repo
This assumes you've two copies of your repository.
The same with pulling, e.g.
git pull /mnt/usb/my_repo
To apply patches, you can use
patch command or
You can use Git locally too. Then your commits are only stored locally, and you still have version control with it (and can diff/merge etc.), but you just can't access the repository from any other computer.
You can start a local Git repository by running
git init in your local folder. As described here.