GIT sucks (3)

Unfortunately I have to make a correction to my previous post.

In that post, I suggested that the following git command would work:

quest util-linux% git clone --bare . ssh://kernel.ubuntu.com/srv/kernel.ubuntu.com/git/scott/util-linux.git

I wholeheartedly apologise.  It turns out that what this command does is make the following local directory: $(pwd)/ssh:/kernel.ubuntu.com/srv/kernel.ubuntu.com/git/scott/util-linux.git.

Unfortunately this means that normal service of hating git, while still being utterly unable to find any reasonable command to do what I want, will have to resume.

All I want to do is run a command to take the branch I have in my local working tree, and put that on a remote server so that other people can get at it.

Failing that, I want sharks with frikkin’ laser beams on their foreheads!

Is either so much to ask?

32 thoughts on “GIT sucks (3)

  1. I use “git push gh branchname”.

    this works for github at least and I had to define “remote” first.

    works like “git remote add gh bla@github.com:blub/repo.git”

    this must somehow work in your setup too :)

  2. Wouldn’t this solve your problem? (taken from the git user’s manual)…

    Setting up a public repository

    Assume your personal repository is in the directory ~/proj. We first create a new clone of the repository and tell git-daemon that it is meant to be public:

    $ git clone –bare ~/proj proj.git
    $ touch proj.git/git-daemon-export-ok

    The resulting directory proj.git contains a “bare” git repository—it is just the contents of the “.git” directory, without any files checked out around it.

    Next, copy proj.git to the server where you plan to host the public repository. You can use scp, rsync, or whatever is most convenient.

  3. You came close to hitting the nail on the head in both this post and the first: What the hell is a “refspec”

    That’s the bit that makes people either “get it” or not. If you can figure out exactly what a refspec is, you gain entrance to the tower. If not, the dragon comes and eats you every time you look at the manual pages.

    It drives me nuts how circular the documentation is, and how it all rests on the definition of refspecs, which are never laid out at all.

    Git does do funny stuff, like letting you push whole repositories rather than single branches — which I think are sane alternatives to an unthinking default — but damnit, the docs make no sense.

  4. another “failing to read user’s mind” problem with git.

    so git is fatally flawed since the correct order is “git clone remote-repo [destination]“? Childish.. Since the last argument (local dir name) can be reasonably set by default from the first argument (basename of repo url perhaps), it kind of makes sense with that order. Hey mostly, you don’t even have to specify it.. git clone –bare repo-url .. really hard!

  5. Ok, I admin reading a tad bit too fast! Scott hoped clone would do remotes clones as well, that the second destination parameter was ok to be remote (ssh or whatever as well). Ok now I understand the issue better.

    @vadim: what’s your point?

  6. That you pulling commands out of thin air doesn’t help someone who’s getting started with git and is patiently going through the manual to be able to accomplish something, when those commands aren’t there.

  7. @vadim: those commands are certainly there, but they don’t do what scott wanted to do, since I misunderstood the post in the first reading. But “git clone [--options] remote-repo” surely is a command, only that “git clone” can only download repos, not upload them.. so what it does is downloading a copy of that remove-repo. And yes, that command exists.

  8. I have to disagree that just because you can’t make it do what you want it to that it sucks. I can’t do differential calculus. Doesn’t mean it sucks. I can’t do a backflip on a bmx but its not the bike that sucks…

    Anyway, to actually post something constructive, first did you clone from that url or from a repo that did clone from that url?
    If not you’re trying to push something git is never going to be able to figure out.

    If I understand you correctly, you are trying to publish a repo… if that is the case you got the wrong tool.

    > scp -r /path/to/your/repo kernel.ubuntu.com/srv/kernel.ubuntu.com/git/scott/util-linux

    If you only want a bare remote:
    > git clone –local –bare /path/to/your/repo /tmp/myrepo
    > scp -r /tmp/myrepo kernel.ubuntu.com/srv/kernel.ubuntu.com/git/scott/util-linux

    Now, add that repo as a remote:
    > git remote add myremote kernel.ubuntu.com/srv/kernel.ubuntu.com/git/scott/util-linux

    You will now refer to that repository as “myremote”.

    Now, make your branch with changes on you local repo:

    > git checkout -b MyBranch
    > touch test
    > git commit -m ‘my super comment’ test
    > git push myremote MyBranch

    That (if i didn’t misinterpret) should do what you asked for.

  9. First, make a bare clone of your existing repo:
    $ git clone –bare ~/repo shared.git
    $ touch proj.git/git-daemon-export-ok # if you want to export using git-daemon
    Then, copy shared.git to your server using scp, rsync, or whatever.

    The above steps are as documented in Setting up a public repository in the User’s Manual.

    Let’s say you add branch new to your local repo and want to push that to new branch in the shared repo:

    $ cd ~/repo
    $ git push user@host:shared.git new:new

    The above step is as documented in Pushing changes to a public repository in the User’s Manual.

    Of course, you could also add a remote in your local repo and do it this way:

    $ cd ~/repo
    $ git remote add shared user@server:shared.git
    $ git push shared new:new

    There are variations on this depending on your workflow needs.

  10. Hi!

    I was also a bit surprised when I discovered an unknown .ssh dir in my git repo. :-/

    It’s probably not the user-friendly command you’re looking for, but I came up with this one-liner:

    ssh -nfNT -R 2000:localhost:22 remote_user@remote_server && ssh remote_user@remote_server “git clone ssh://local_user@localhost:2000/~local_user/path/to/local/git_repo path/to/remote/git_repo”

    You can use this command as local_user to clone your local repository (in ~local_user/path/to/local/git_repo) to a new repository (in path/to/remote/git_repo) as remote_user on remote_server.
    You still end up with a remote SSH tunnel from local to remote that should be killed once you cloned the repo : (ps aux | grep ssh)
    And you need sshd running on both servers!

  11. Not sure what the difficulty is. I’ve not had to set up a remote repository with git before, but just tried doing so according to the instructions Michele linked to in the manual – in particular, the bits titled “Setting up a public repository” and “Exporting a git repository via http”. Worked perfectly, no fuss.

    $ git clone –bare ~/proj /home/you/public_html/proj.git
    $ cd /home/you/public_html/proj.git
    $ git –bare update-server-info
    $ mv hooks/post-update.sample hooks/post-update

    Sure, something like ‘git setup-remote-repository ~/proj /home/you/public_html/proj.git’ would be nice, but the above 4 commands aren’t too bad unless you’re creating new repositories frequently.

  12. I’m a little confused by your first post and now this one… in your last post you kept saying, essentially, “why does the manual keep pointing to ‘git push’ if it’s not the right thing to do?” Well… it *is* the right thing to do. So, let’s assume you have already created your git repo on kernel.ubuntu.com, probably using “git init –bare”. You have to do this *on the local machine*. That is, on the server. Or you can do this on your machine at home, and then tar up the git repo and untar it on the server.

    Now say you have your repo $myrepo at home on your local machine, and you want to publish your local branch ‘master’. So, from home, you do:

    cd $myrepo
    git push ssh://kernel.ubuntu.com/srv/kernel.ubuntu.com/git/scott/util-linux.git master:refs/heads/master

    Yeah, that’s it. And it’s ugly. And you “just have to know,” AFAIK. Or maybe that’s in the tutorial somewhere… I dunno.

  13. RTFM

    Heck, that’s what I did, and I don’t think I was born with an superior understanding of manuals ingrained in me. And there’s also this thing called the web, ya know, and you can search it and find tutorials! And even, there’s thing called a blog, and aggregators, and also mailing lists, and you can actually ask for help if all other resources fail! Isn’t that amazing?

    Sarcasm aside, I’m sure everyone has told you exactly what to do, but I’ll just be annoying and do the same. Whenever I want to share code with my boyfriend who just happens to have ssh access to my machine, I go somewhere on my hard drive, create a dir and do

    git init –bare

    and then I go to my code (which is on git already, obviously), and do

    git add remote cute_name_for_remote_repo /path/to/the/dir/I/created/above

    and then I just have to push whatever I want, be it a branch or master, to this new cute_name_for_remote_repo, like thus:

    git push cute_name_for_remote_repo name_of_branch_I_want_to_share_with_my_boyfriend

    Now he can just do git clone ssh://path/blabla and get all my wonderful code.

    See? Now wasn’t that easy? Have fun!

  14. I won’t defend git’s man pages at all, although there are some good resources outside of the man pages (the git community book, for example) that are better. And as other people have already suggested, the easist thing to do is to use pre-existing services such as github or git.or.cz to set up a remote pull-point or to allow centralized collaboration (which is something git doesn’t optimize today, no question).

    The key actually is to have to proper setup in your .git/config file. Which you can edit via “git remote”, but personally, I find a text editor on the actual .git/config file is much easier.

    In my ext4 kernel tree, I have the following in my .git/config file:

    [remote "master"]
    url = ssh://master.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git
    push = +master:master
    push = +for-stable:for-stable
    push = +for-stable-2.6.27:for-stable-2.6.27
    push = +next:next
    push = +for_linus:for_linus
    push = +origin:origin

    Once I have this, all I have to do when it’s time for me to do another release is to do a “git push master”. That’s it. No muss, no fuss, no dirty dishes. This will replicate *only* the branches master, for-stable, for-stable-2.6.27, next, for_linus, and origin to the ext4 repository at master.kernel.org (which then gets replicated every 15 minutes or so to git.kernel.org and git2.kernel.org via kernel.org’s mirroring system).

    Here’s what I have for my e2fsprogs repo:

    [remote "publish"]
    url = ssh://master.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
    push = e2fsprogs-interim
    push = next
    push = master
    push = maint
    push = +pu

    In this case, I keep an /usr/projects/e2fsprogs/base which is a bare repo on my hardrive, and I make sure it looks exactly right before I push it to master. So this file lives in /usr/projects/e2fsprogs/base/config (there is no .git directory, since this is a bare repo). There are no ‘+’ signs in front most of the branch names, since they are “well-behaved” branches that are never rebased. The ‘+’ disables a safety mechanism for git that warns if the local branch which you are pushing to has been rebased, since if other users have cloned from the repository and have started developing off that starting point, doing a forced-push can make life difficult for them, unless they know to expect that the branch heads are unstable and can be rebased at any time. In the case of e2fsprogs, this is true only of the “proposed update” (‘pu’ branch). In the case of the ext4 kernel tree, since I don’t have any downstream repositories that are forked off of the ext4 tree (I have a “leaf” repository), I can rebase with a much greater level of latitude, and I take advantage of that.

    In any case, part of the problem is that git man pages are far too much like reference manuals, and you have to pick a tutorial which is far more specific for a particular workflow you want to follow. For example, the github documentation is pretty good at showing you how to use the centralized SVN-style workflow, if that’s what you really want to use. Once it’s set up though, I can assure you that most people don’t end up typing long URL’s and refspecs each time they want to push things out to their centralized repository. The real problem here is the documentation.

  15. You’re absolutely right: in any well-designed version control system, publishing a bunch of stuff you’ve been working on should be a one-line task. All you should need to do is specify what you want to publish (default whatever you’re working on), and the destination URL.

    Yet the Git fanboys come in with their 7 line recipes and hacked-together shell scripts, and are apparently unable to see that there’s something very wrong with that picture. Instead, you must be the idiot, and must have expected git to “read your mind”.

    It’s hilarious. Sad, but hilarious.

  16. So you would find receipe not in “Git Tutorial” (which covers only basic operations, and does not consider creating public publishing repository basic), but in “Git User’s Manual” (and I assume also on book.git-scm.com).

    Basically you have to create repository on the remote side before you can push into it. And to push current branch it is enough to use “git push HEAD” (“git push ” will push matching branches, IIRC), but it is better to setup configuration for that.

    As to manpages being cryptic: first, they are *reference* documentation. Second, they are created (usually) by advanced git user’s, who know git back and forth; therefore contributions to manual from new to git users are very much appreciated (git mailing list is open to all, and is available via NNTP interface on GMane).

  17. And to push current branch it is enough to use “git push <url> HEAD” (”git push <url>” will push matching branches, IIRC), but it is better to setup configuration for that.

  18. Git will have in the future “git init –remote=”host:directory” – the patches have just appeared on git mailing list (they need some work).

  19. You should really look into gitosis: it makes publishing stuff really easy, as well as managing access to your repositories. Also, with my patch (http://git.kitsu.ru/patched/gitosis-gentoo.git/commitdiff/71cb44351f9511ecf628a6aa674da8364a0f1086) you could even add wildcards in your gitosis-admin, and then any matching remote directory would be automatically created for you (so you won’t need to add every project to gitosis-admin before publishing). With all this, git is much more controllable and easy to publish, than say Bazaar.

  20. Thanks for the good reads Scott. I’m just getting started with git, and I feel your pain.

    I’ve been a professional programmer for six years. I’ve delved into different Linux topics for just as long. I’m intimately familiar with using man pages. Google is my best friend. I’ve read tutorial after tutorial on git. And still, I have problems doing simple things: setting up a remote repository location, making this location secure, making this location accessible, how do I get my local tags to remote (use the –tags option with git-push), etc.

    I’m migrating from Subversion, and I definitely see git as the superior tool; however, there is no reason why documentation and interface design cannot meet the needs of both the novice and the advanced users. The git project has been around this long and still is geared almost exclusively to people in the know. This is unacceptable.

    As for setting up a new remote repository, there is no reason for it to require the steps people have listed here. Yes, I know I can copy the freakin’ thing with scp. Yes, I know that I can set up a bare repository while actually on the remote box. Yes, I also know all the little config tweaks necessary to make the thing actually work. What I don’t know is why if I want to allow other people to be able to create repositories on my repository server do I have to give them SSH, FTP, or other file access to my box. Answer that for me please.

    I’m sure some will retort “why would you trust someone to make repositories but not trust them with a user account?” Does it really matter? The point is that it should not require me to set up additional configurations outside of git itself to allow people to create a new repository. This means that I should not have to create SSH or FTP users, use third-party tools, or write a customized solution to allow people other than myself to create new repositories. Furthermore, the solution to create a new remote repository should be simple and intuitive.

  21. I know I’m late, but so far this is what I’ve figured out about git and why is it so hard to “push” things:

    There is no such thing in git as a “central repository”, there’s only “people” with their repository. It stands to reason that you can’t push your changes into others, you can only ask others to pull changes from you.

    The so-called “central repository” that people use, is simply some sort of machine-driven user or “person” with its own account and repository. So in some way, you’re supposed to ask this “machine” to pull the changes from your personal repo. And that’s where github and other additional server-side programming comes in, kinda like a remote control for these faux-users.

    Sounds like a lot of fun ؟

  22. @Sergius Maximus: It is true that in (most) DVCS such as Git the notion of “central repository” is not technical but social issue. But while one of workflows used with Git is to have ‘maintainer’ persona, who pull from other contributors and apply patches send via email, there also exists “centralized” workflow (“commit-bit” workflow) where multiple people push to the same repository (perhaps only to selected subset of branches).

  23. If you are new to git, you might find working “from the other side” (that is, git-pull and git-clone) much more intuitive.

    Git is the first VCS I used, and I still find it more “logical” than any other. However, I found git-push confusing at first.

    Anyways, if everything seems confusing and arcane to you, a good starting point is “Understanding Git Conceptually” (http://www.eecs.harvard.edu/~cduan/technical/git/)

  24. @Jacopo, that is a very useful link; I agree that your only hope of understanding git is to have a good conceptual understanding of it…since those concepts differ from virtually every single other VCS I’ve ever touched in my career. I wish I’d read it a couple of years ago (when both git and the paper were relatively new and shiny). Better still, it would be fantastic if the git people and Mr Duan couldreach an understanding whereby a version of this paper could be incorporated into the standard documentation for git (to the degree that that isn’t mutually contradictory).

    One of the valuable things that Charles Duan does in his writing is to point out, almost offhandedly, the things that were “tacked on” to git to meet a need, that later became part of the “it’s all here and easy to use if you’re smart enough” mythology of git.

    The sad part, of course, is that an attitude like this is not only justifiable, but a necessary survival trait. I recently worked with a team where the client lead had named the git server ‘sal-si-puedes’; nobody else got the reference. They’re now a quite happy (and multiply more productive) Mercurial shop.

    As in, the full name of the software in question is “git away from this!”

    YMMV, IANAL, LSMFT, YCHJCYADFTJB

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>