John Reed Avery
John Reed Avery

Reputation: 141

Cannot figure out specific Git syntax to "push" only a single file

It might not matter but I'm attached to the GitLab server with the SSH URL, rather than the HTTP(S) URL.

On the GitLab server, the path to the Project is (I'm gonna fake part of this for security purposes):
Group/Group/Project/subdir = Engineering/Bladelogic/Scripts/test

The closest I've come to success, in specifying a single file and getting a successful "push", is this:

$ git push origin development {commit-hash}:refs/{commit-hash}

But there are two problems:

  1. The above command (successfully) pushes everything that is presently committed and not yet pushed, rather than only the 1 file whose hash I specified.

  2. Even though it effectively pushes something, I still get the following screen-output, which includes the partial errors indicated below:

Counting objects: 17, done.  
Delta compression using up to 2 threads.  
Compressing objects: 100% (10/10), done.  
Writing objects: 100% (12/12), 1.19 KiB | 0 bytes/s, done.  
Total 12 (delta 4), reused 0 (delta 0)  
remote: error: refusing to create funny ref 'refs/62ce94830fa2753ef8ca3bb28d74dbe0cea39ead' remotely  
To git@<FQDN>:Engineering/Bladelogic/Scripts.git  
   9e722dd..62ce948  development -> development  
 **! [remote rejected] 62ce94830fa2753ef8ca3bb28d74dbe0cea39ead -> refs/62ce94830fa2753ef8ca3bb28d74dbe0cea39ead (funny refname)**  
**error: failed to push some refs to '[email protected]:bts-tools-engineering/tssa/BladeLogic-Scripts.git'**  

Is there a way to push only 1 presently-committed file and, if so, what am I doing wrong?

Upvotes: 0

Views: 119

Answers (2)

jthill
jthill

Reputation: 60295

If you really want to push just one file, tag that file and push the tag:

git tag myfile master:path/to/that.file
git push origin myfile

and then people fetching that tag will get just the one file -- which Git's convenience commands won't really know what to do with, but Git itself? Sure.

As a quickie testcase:

$ cd `mktemp -d`; git init
Initialized empty Git repository in /tmp/jthill/tmp.wKE9Fx3zCz/.git/
$ echo test > test.file; git add .; git commit -m demo
[master (root-commit) fe3c6c5] demo
 1 file changed, 1 insertion(+)
 create mode 100644 test.file
$ git tag myfile master:test.file
$ git init `mktemp -d`
Initialized empty Git repository in /tmp/jthill/tmp.PXlls8ZgK3/.git/
$ git push $_ myfile
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 46 bytes | 46.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
To /tmp/jthill/tmp.PXlls8ZgK3
 * [new tag]         myfile -> myfile
$ cd /tmp/jthill/tmp.PXlls8ZgK3
$ git show myfile
test
$

Upvotes: 1

bk2204
bk2204

Reputation: 76509

There is no way to push only a single file. Git's protocol is designed around finding a set of commits and tags that are in common and sending the objects that one side has and not the other. That necessarily involves walking the history, which practically requires commits or tags.

If you want to make a changes to only a single file, you can put those changes in a separate commit and push only that. For example, if you want to create a new commit out of the state of file foo on branch branch, you could do git checkout branch:foo and then commit, which would create a commit that contained only that file.

But as for pushing just a single file, that's not possible. A tag or commit is going to be needed.

Upvotes: 4

Related Questions