

Die Git Die - reinhardt
https://github.com/regebro/die-git-die

======
wonderzombie
I'm not trying to argue that git is divinely inspired or whatever— this is
confusing behavior.

 _It tells me I can lose history, but this is a revision control system,
surely they don't mean I can actually lose history?_

Sorry, but why did you think that they said that except to tell you that you
could actually lose history? You ignored the rest of the error message and
used --force. And then you were surprised that what the error message told you
actually came to pass?

~~~
pifflesnort
It still is a broken design that you can ever lose history or hose a
repository in a tool that is designed to store history, forever.

That's a sharp edge that should be exposed, and its not the only one in git.

~~~
jrdn
I really, really want to be able to lose some history sometimes. Like if
someone checks in sensitive user data by accident. Rolling it back is
insufficient, I want that _expunged_. Maybe git doesn't do it perfectly, but
it has reason to do it.

~~~
lennartregebro
Sure, that's OK. But shouldn't that command be _explicit_?

------
endlessvoid94
I don't know why, but I always end up telling every single person who either
1) Bitches about git, or 2) asks for help, that I always, always, always tell
"git push" or "git pull" which remote and branch.

It's muscle memory and makes everything more explicit and easy to understand.
Although, in this case, it sounds like you expect git to be intuitive. (Which
it is not)

So this basically amounts to a blog post complaining that git is hard.

~~~
kstenerud
It's a problem of user interface design. Git's user-machine interface does not
follow the principle of least astonishment. It's not orthogonal. Functionality
is grouped in very strange ways (you list, move, rename and delete branches
with branch, but create branches using checkout? Seriously???).

And don't even get me started on the nightmare that is submodules.

The whole thing reminds me of the bad old unix days of "if it was hard to
write, it should be hard to understand."

~~~
damncabbage
_you list, move, rename and delete branches with branch, but create branches
using checkout? Seriously???_

    
    
      git checkout -b new-branch
    

... is a shortcut for:

    
    
      git branch new-branch
      git checkout new-branch
    

You can create the branch or otherwise manipulate it without actually checking
it out, so it's useful to have it separate _and_ have a shortcut.

(I agree that git's interface is terrible, but I disagree that this is one of
those cases. :) )

~~~
sjwright
> but I disagree that this is one of those cases

I do think this is precisely one of those cases.

"Branch" is a major, repo-modifying operation; "checkout" is a trivial context
switch operation. The user interface disaster here was that the major
operation is treated as subservient to the trivial operation. It should be the
other way around.

Therefore, the shortcut for creating a branch and switching to it should be

    
    
      git branch -c new-branch
    

whereby the -c switch checks you into that branch immediately.

~~~
johnny22
branches aren't supposed to be "major". That's the major difference between a
system like git and svn. branches are cheap. They are supposed to be used
often and even be disposable.

~~~
nessus42
Indeed. "git branch" is a lot like "mkdir". If you accidentally make a branch,
deleting it with "git branch -d my-branch" is about as easy as typing "rmdir
my-dir".

~~~
sjwright
Nobody would argue that mkdir is a more major operation than cd. Which is my
point.

------
jrockway
"The git, the?"

But seriously, yes, you have to learn how to use Git in order to use Git. But
you don't have to use Git. Click here to renew your Visual Source Safe
license, or better, just copy your file to file.1 every time you edit it. No
way that can go wrong!

~~~
stormbrew
You say that, but the next version of Visual Studio's gonna have git built in.
Seriously. Gonna be a lot of new (and probably confused) users out there.

~~~
spo81rty
But VS won't require using command line

~~~
lucisferre
You'd think that would be a good thing, but I highly doubt it. Visual Studio
and .NET in general is not generally known for it's exceptional use of
abstractions.

------
egonschiele
I totally agree that this is surprising behavior. But git did try to tell you:

    
    
        ! [rejected]        master -> master (non-fast-forward)
    

And once you've invoked the gods of `push -f`, you're on your own.

~~~
morsch
As someone who's only used git in fairly straightforward ways, that line is
complete gibberish to me.

~~~
egonschiele
It's saying you tried to push the master branch (`master -> master`) and it
was `rejected`. Since he made a bunch of changes to the master branch from
another dir, _of course_ his changes are not going to get pushed.

------
defen
> However, git will not _pull_ matching branches. That means that all your
> branches except your current branch will not get updated when you pull.

> Of course, a less good but at least sane behavior would have been if pull
> also pulled matching branches by default

I don't see any way this could work in the face of potentially having merge
conflicts in non-current branches.

~~~
cjh_
This is the reason pulling all matching branches (and pushing all matching
branches) by default is generally a bad idea.

------
peff
I notice that he omits the full output of `git push`. A lot of the confusion
is caused by the fact that the default push mode is `matching`. I don't know
what git version he is running, so I can't say exactly what text was omitted,
but I would have expected to see two things:

1\. Not only mention of the rejected `master` branch, but also the successful
push of the `gh-pages` branch. Which makes it a lot more clear that git is
trying to push multiple branches, and that the rejection has to do with
`master` and not `gh-pages`.

2\. The push default of `matching` is changing soon in upstream git (because
it is suitable for certain types of workflow, but can cause confusion, as seen
here), and the last several versions complain loudly if you do not set the
default. This is intended to call attention to this common pitfall, and to
notify users so that they are not surprised by the change when it happens.

With git v1.8.2, here is the full output of `git push` in his situation (you
may note that the non-fast-forward advice has been improved, too):

    
    
      $ git push
      warning: push.default is unset; its implicit value is changing in
      Git 2.0 from 'matching' to 'simple'. To squelch this message
      and maintain the current behavior after the default changes, use:
      
        git config --global push.default matching
      
      To squelch this message and adopt the new behavior now, use:
      
        git config --global push.default simple
      
      See 'git help config' and search for 'push.default' for further information.
      (the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
      'current' instead of 'simple' if you sometimes use older versions of Git)
      
      Counting objects: 8, done.
      Delta compression using up to 8 threads.
      Compressing objects: 100% (2/2), done.
      Writing objects: 100% (6/6), 428 bytes, done.
      Total 6 (delta 0), reused 0 (delta 0)
      To /home/peff/foo/die-git-die/parent.git
         148db6f..25cd4ef  pages -> pages
       ! [rejected]        master -> master (fetch first)
      error: failed to push some refs to '/home/peff/foo/die-git-die/parent.git'
      hint: Updates were rejected because the remote contains work that you do
      hint: not have locally. This is usually caused by another repository pushing
      hint: to the same ref. You may want to first merge the remote changes (e.g.,
      hint: 'git pull') before pushing again.
      hint: See the 'Note about fast-forwards' in 'git push --help' for details.

~~~
lennartregebro
It's nice to know things have improved. Apparently they will also remove the
stupid "matching" default on push in version 2. But I think that pull and push
still will not do exactly the same in choice what to pull and push even in
version 2, as I understand it. Which still is bad.

------
Legion
> However, git will not pull matching branches. That means that all your
> branches except your current branch will not get updated when you pull.

This is why git-up was created: <https://github.com/aanand/git-up>

It's silly that this is necessary, but "gem install git-up" and then run "git
up" instead of "git pull" and you'll be much happier.

------
stormbrew
Git has a lot of UI problems. This is not really surprising. It's gotten a lot
better, but I do think that no matter how proud Torvalds is of the fact that
he never looked at another version control system for inspiration, a lot of
pain could have been avoided if he had (even while still going in the
different directions he did). Not all of us had the 'luxury' of never working
with version control before.

But don't get me wrong. On the whole, git is fantastic and a real improvement
on its predecessors.

~~~
glurgh

      >no matter how proud Torvalds is of the fact that he
      >never looked at another version control system for
      >inspiration
    

What gave you that impression? Git was strongly influenced by BitKeeper and to
a much lesser extent by Monotone. And, arguably, 'anti-inspired' by several
other VCS's Linus would have surely been at least passingly familiar with.

~~~
stormbrew
There's a rather famous video of him talking about how wonderful his lack of
experience with traditional VCS' was for producing git. Obviously he had used
bitkeeper (but wasn't very fond of it), and he was probably exaggerating a bit
even after that.

I think most of the outside influence came from people who weren't Torvalds,
but the command set is just so weirdly different from every other VCS (even
where functionality maps nearly 1:1) that it seems likely that it was designed
without much consideration for existing use patterns of other VCS'.

~~~
glurgh
I haven't seen the video but generally he's been very complimentary of BK:

[http://marc.info/?l=git&m=114685143200012](http://marc.info/?l=git&m=114685143200012)
[http://marc.info/?l=git&m=116129092117475](http://marc.info/?l=git&m=116129092117475)

And two basic verbs 'pull' and 'push' are straight from BK.

My impression's been that the crazy command set is in part due to the early
design idea that the basic commands represent primitives that operate on the
fundamental git model on top of which something, potentially separate and more
human-friendly will be built. Except it didn't quite work out that way.

------
syncerr
Whenever I'm pulling down code, instead of `git pull', I use fetch. I fetch
the specific branch into the local remote tracking branch (remote/branchname).
Then use rebase, rather than merge. I won't lose anything and it avoids those
dumb merge commits. Also, aliases are great for this.

    
    
        git fetch <remote> <branchname>:refs/remotes/<remote>/<branchname>
        git rebase <branchname> <remote>/<branchname>

~~~
kemayo
That's equivalent to just doing `git pull --rebase`, no?

~~~
syncerr
`git pull --rebase` does not update my remote tracking branch. Though you may
not care about this.

~~~
__david__
The "git pull" man page states that "git pull --rebase" is exactly equivalent
to "git fetch" followed by "git rebase" so I'm not sure why it wouldn't update
your remote tracking branch (since that is what "git fetch" does).

------
Muromec
Well. Actually you are using git in place where svn or rsync should be enough.

Just look at git.kernel.org - over 400 repos only for linux kernel. This is
what git designed for - to be Mass Distributed Version Control System.

So are using it as tape archiver and wondering why defaults look so unfrendly.

~~~
bumeye
You make it sound like git is unsuitable for this, i disagree. I often use git
for one-man projects, both with and without an external repository. Once you
learn how to use it it works great. I would never want to return to
svn/rsync/zip-files.

~~~
Muromec
>You make it sound like git is unsuitable for this, i disagree

It's not me, it's post author who makes it sound so. Actually it's up to user
to decide what is suitable for him and what is not.

------
verelo
I am so glad someone wrote this up and shares my frustration.

I've been through this exact battle so many times, git pull should only ask
you for your branch if you've told it you want it to (as a safety measure i
guess)/

------
178
He is using a hack to store the GitHub pages. That this is even possible is
due to the awesomeness of git. Since it is a hack, you have to be careful what
you're doing. He should have done all the gh-pages stuff in a separate clone.
The GitHub instructions where he pasted the branch creation commands from also
tells you to do just that. Keep the pages branch in a clone of the repo inside
the repo, just in a folder called 'docs'. You'll never have to mess with these
branches, as you can generate docs, commit and push from a Makefile.

------
zllak
You can't blame git where you clearly didn't fully understand how it works,
and you _clearly_ ignored its error messages, and used the -f option. There's
some very useful tools like "tig" to check the state before pushing. A good
rule of thumb is to never push -f before being absolutely sure of what it's
going to do. And everything is not lost, you can still use "git reflog" to
retrieve the previous state. You're whining about git where you are clearly in
fault here :)

------
eridius
This just seems like yet another case of someone who thinks he's too smart to
read the manual. RTFM exists for a reason.

------
roryokane
EasyGit (<http://people.gnome.org/~newren/eg/>) fixes this problem. It’s a
command-line wrapper for Git that makes some interfaces more usable. `eg push`
pushes only the current branch; you must write `eg push --matching-branches`
to do what `git push` does.

EasyGit also provides better built-in documentation. For example, if you get
merge conflits, `eg status` will mention that you can run `eg help topic
middle-of-merge`. That command opens a page explaining your options – how to
find conflicts, resolve conflicts, etc. I have found EasyGit very useful, and
when it’s installed, I always use `eg` instead of `git`. You can download the
EasyGit script at the linked website, or install it using Homebrew with `brew
install easy-git`.

------
harshreality
Code section 3: why create a new clone of the repo when all he needed was to
create a new branch and modify that?

Code section 5 and 6 are apparently modifying the code branch, and the pages
branch, respectively, but doing so in separate local clones of the repo. I
think there's a typo in code section 6, where I think he meant to start with

    
    
      cd ../die-git-die.pages
    

This doesn't seem like a situation where multiple local git repos are needed.
What's wrong with managing both branches from one local repo?

~~~
bumeye
This is the way that github recommends
([https://help.github.com/articles/creating-project-pages-
manu...](https://help.github.com/articles/creating-project-pages-manually)).

A separate folder for the gh-pages branch makes sense because this branch has
nothing in common with any of the other branches. It doesn't share any code or
commits with your master branch.

The repository actually has two base commits and it's like two repositories
contained in one. Thus needing two separate folders.

------
nessus42
_> $ git push origin gh-pages_

I think that if you had changed the above to

    
    
        $ git push -u origin gh-pages
    

then everything else would have gone smoothly.

~~~
kansface
This is what I do personally. We also use rebases liberally at my office which
requires us to force push upstream. On-boarding new team members scares the
shit out of me.

~~~
encoderer
I hear ya, but as you obv know as long as you're pushing to a location only
you are pushing to, a force-push is harmless.

Moreover, any loss that does occur is recoverable as long as you keep your
clone around. Git doesn't garbage collect refs for at least 30 days. So you're
pretty protected if you clone to a location that has regular backups.

------
Cryode
I'm grateful for the Tower GUI app. Just wish it would tell me what commands
it was using, since I'd like to know.

------
tingletech
Anyone use <http://www.git-legit.org> ?

Looks like it was inspired by a hackernews comment
<https://news.ycombinator.com/item?id=2684483> and it replaces these commands

------
hemphill
I've gotten in the habit of always adding the remote and branch name when
doing a pull or push. Seems to avoid all these issues.

------
Shamharoth

      man gittutorial

------
abimaelmartell
you need to read "Git for dummies"

~~~
kansface
git has no user interface. git expects its users to have an in depth
understanding of its implementation details. These are failures of git.
Ideally, studying abstruse man pages to avert disaster wouldn't be required of
new users.

~~~
Rarebox
Git interface is hard, because git is hard. Git is hard because it is so
powerful. Git developers don't care about newbie users who can't even bother
to RTFM. There is just no reason they should.

Git user interface is fine when you finally learn how to use git.

~~~
LeonidasXIV
A browser is hard. Firefox is easy.

I don't think your reasoning holds. That's why we have abstractions, to make
hard things easy.

~~~
Rarebox
The idea of a browser is far easier to understand than git from users
perspective. Implementation is something user doesn't have to know about (for
firefox or git).

What makes git so powerful is that it doesn't abstract things as much as other
systems. To make git easier would mean making it less powerful. I rather use a
tool that is complex than a tool that doesn't let me do what I want.

------
trotsky
git was designed by and for people who read man pages. the fact that it has
significant usability problems is a problem for them only in so far as they
are interested in having you contribute code to them, which is to say very
little.

Github is the one who wants you to use git. This is why github built you a
gui.

------
ams6110
s/git/hg/ and get on with life.

