简体   繁体   中英

Is it possible to add a file to a git repo without having it checked out locally?

Goal: Add a new file to a remote git repository without checking the whole thing out locally.

Why: I'm building an app that will add files to a user's git repository. Some of these repositories will be hundreds of megs. Some will be touched very infrequently. I want to avoid taking up terabytes of disk space to keep large repos checked out that won't be touched often, and I don't want to incur the inevitable delay of checking out a 200Mb repo (lots of binary files) in order to add a new one new file to it and push that file back to the origin.

I'm assuming the default git client can NOT do this, but am hoping that someone has written something that can commit to a remote repo (don't care what language) without having the whole thing checked out locally. Does the Cloud9 IDE do something like this?

The app would have full access to the users git repo, either via SSH or whatever mechanism GitHub uses for oAuthed apps to tweak repos.

Depending on the structure of your repository, you may be able to use sparse checkouts to avoid downloading the large files:

http://schacon.github.com/git/git-read-tree.html#_sparse_checkout

(More information at Checkout subdirectories in Git? )

Git has several options for shallow cloning and filepath specific, partial cloning but these are not pushable.

The trick here is to utilize the --lightweight flag when you checkout - in which case, you will be able to push to a limited repository.

However, these solutions appear severely nonideal... Seems more intuitive that , If the app has programmatic access to a git repository, then you should be able to create, or require on installation the creation of a git project that is specific to your application's needs, which is empty.

If you have shell access to the repos, you can create a fast-import file (see the manpage of git-fast-import for the details of the file format), and execute git fast-import inside the remote repository.

When you don't have shell access, the solution is much more hackier. You need to execute the following tasks to push your changes to a remote repo:

  • create the content of all files (=generate the hash of the new file, and find the hashes of the unchanged files [you get them from the current tree])
  • create the tree
  • create the commit
  • push the new file content, tree and commit to the remote repo
  • push the branch-move to the server

I would start with the hg-git extension, since I guess that there is some code which does something similar.

WARNING: THE FOLLOWING ANSWER NO LONGER WORKS WITH THE MOST RECENT VERSIONS OF GIT

(I'm open to suggestions as to how to make this work with current git versions.)

The answer, it turns out, is amazingly simple, and a testament to just how awesome Git is.

  • Create a brand new git repo.
  • add and commit the new files to it.
  • tell the new repo where the remote repo is (git remote add ... )
  • push to the remote repo.

Notes: The remote repo must either be a bare repo or have receive.denyCurrentBranch set to "ignore" or "warn"

This is based on the assumption that the files you are adding are NEW and will not conflict with any other file in the repo.

The existing contents of the remote repository do not matter so long as you can be sure you're not going to conflict with anything.

PS Thank you to everyone who posted the potential workarounds.

How about a 2nd lightweight repository with just the files you need to add, a script on their end could check out both repos and add your files. That script could also remove the consumed files from your new repo to keep it lightweight.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM