Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> The set of different options (normal merge, rebase, filter-branch, etc) is complex and not cleanly orthogonal

All of those commands you just listed are clearly defined and serve different purposes. In other cases, most commands or command flags simply help the user do something in an automated fashion that you could do by typing each specific command out (i.e., git pull --rebase). Git's core tooling is mainly centered around graph manipulation, everything else has been added due to convenience. And quite frankly I've never really understood the criticism people levy at git for being "complicated."

It's stupidly simple at the end of the day, especially compared to the hodgepodge of features that other VC's provide, all of which don't really work together and are designed to cover some gap in what should be handled in the core design of the VC (I'm looking at you, Mercurial branches and bookmarks). All tools require you to be familiar with them. There's no getting around that.

> Even experienced experts would have difficulty finding the clear, simple way to solve this problem

I'm not sure how you can possibly say that, the answer is pretty obvious to a lot of us reading this article. This just feels like baseless whining.

There is a litany of literature out there that could have easily pointed the author to a well defined, accepted, and documented solution.



> It's stupidly simple at the end of the day

That reminds me a joke. On a particularly convoluted math lecture the professor writes on the whiteboard and explains at the same time: "from here we can state that, obviously..." He suddenly stops, slowly turns the head down, keeps mumbling "so we can obviously...". He slowly walks in the room, trying to catch the thought, then leaves the room... Some minutes pass. Then he comes back, with head up, widely open eyes and confidently continues - "Yes, this is completely obvious - so from here we can easily get the following conclusion."

Git has a lot of nice explanations. However it's either a particularly edgy case, or all those great explanations somehow fail to easily conduct those core "stupidly simple" ideas forward to actual Git beginners. At least to some of those beginners - not an insignificant number.


I mean, i just find any defense of Git's "simplicity" hilariously unobservant. I'm sure to many Git is perfectly simplistic in design and UX. It is clear, and well thought out.

But, for many others, Git is a confusing mess. And, i should think, nearly everyone has heard someone(s) call Git confusing. I don't think it is up for debate that Git is known for being confusing.

Who cares if it "is" confusing or not - that's relative. Most things aren't confusing if you've learned the subject matter.. right? It is known for being confusing though, and that is clearly to people who don't know Git. Ffs, there wouldn't be debates about Git's UX every month on HN if it was so utterly non-confusing, haha.

Some things are very simple and easy to learn, use, and adopt. Git is not one of them, clearly and objectively.


One thing often missing from the debate is this: version control is a fundamentally complex problem. In my view, it's a unfair to blame this complexity on the tools. The cockpit of an airplane is famously complex not because Boeing and Airbus wanted it that way but because flying a plane is complex, and because they couldn't make it any simpler.

Git has a fundamentally sound architecture, and with a correct mental model of what's going on you'll be able to deal with pretty much any situation. Nevertheless, you won't get beyond the simple use cases if your conceptual picture is incorrect, but that'll be the case for any VCS. I don't believe that git is necessarily superior to mercurial or take-your-pick, but let's not disregard that we're dealing with something difficult.


Version control is complicated, but git adds a whole nother layer of bullshit on top of it. Why do you use checkout to change a branch, create a branch and revert a file? Not because version control is hard, but because as a CLI, git does many things wrong (example from http://stevelosh.com/blog/2013/04/git-koans/).


> Why do you use checkout to change a branch, create a branch and revert a file

git checkout lets you check out files from a particular point in time. If you don't specify a path, it will check out every file. If you don't specify a point in time, it defaults to HEAD (like every git command). I fail to see what is confusing about that. You're not "reverting" changes to a file, you're just checking out a version of the file from the history.

`git checkout -b` is shorthand, and is shorthand that I personally don't use.


> One thing often missing from the debate is this: version control is a fundamentally complex problem.

No, it's not!

I've been teaching SVN to Electronics Engineers, Designers and other folks who have never used version control before. It's always been very straightforward. They'd be able to use it effectively after a quick tutorial and demo, with a few notes of advice.

I've been teaching Git recently... until I gave up. It's a giant WTF clusterfuck. Git is the ultimate failure in simplicity and user experience.

Just use SVN (it works on git repo).


> No, it's not!

Yes it is. SVN is so "simple" because it doesn't have many of the features needed by large teams working on code. It's simply not fit for purpose.

> Just use SVN (it works on git repo).

Unless you need branches (and merge them), code that doesn't get silently corrupted, a proper history of all changes, the ability to work offline without connecting to a server. Y'know, the problems that git was built to solve.


> Unless you need branches (and merge them),

I use svn to merge branches every day. I do agree that git is probably more useful for more complicated setups, but svn is very capable of branching and merging.


> I use svn to merge branches every day.

Has it gotten any better with conflicts? From what I heard a few years ago, it's still absolutely shocking (if two people touch the same file you can forget about merging your branch).


I typically don't have any issues, but I guess that would heavily depend on your workflow.


My problem with Subversion is that it only really works well for trivial cases where you have linear and non-overlapping changes. It's great for configuration management, but not much else.

If you have more than 1 person doing simultaneous changes to a repository which might overlap, SVN becomes a pain to use because its merge handling is basically "Oh, there's a conflict. Here is the whole mess, good luck!" and you lose access to all the tools SVN provides for normal use.

Git (and hg) treat merges as an everyday thing, and a merge conflict does not leave you unable to do basic things such as commit or stage changes with the index, which is a huge help when resolving large conflicts.


I've met people who have given up entirely on merging SVN branches. They just copy changes around manually. Coming from git, I thought their overly-cautious usage of svn was ridiculous. My attitude changed when I ran into revprop issues merging my changes and struggled to discover why some commits seem to randomly be missing svn:mergeinfo. I only had so much time to deal with the issue, so eventually I gave up on fixing the problem and just generated patches to apply manually to the other branch.

One thing I always worried about when experimenting with commands in SVN was that I'd permanently screw up the server. With git, I was comfortable in the knowledge that as long as I didn't push, at worst I would screw up my local repository. Even better, I could just make a copy of that local repository before trying something I wasn't sure about. I haven't had to do that in a very long time, but it was nice while I was learning.

git is not the first version control I tried, but it's definitely the first that really made sense to me. Sure, there's a bunch of badly named commands to memorize, but the underlying concepts they represent are simple.


Personally, I find darcs lovely to use. It avoids complexities like branches (you already have a filesystem - if you want to work on multiple things, you can have multiple checkouts) and provides a simple UI that shows you what you're doing every step of the way by default.


Try Mercurial. It's mental model maps more directly to SVN.

I have successfully taught it to people like CEO's and CTO's with very little difficulty.

The problem with Git is that it has 3 areas of state (working-index-repo) instead of 2 (working-repo).

That makes things HORRIBLY complicated for the 99% of useful use cases.


+ there are nice tools like RhodeCode to work with Mercurial repositories.


Git is not "simple" from the point of view of new users. But it is "simple" from the point of view of the programmers of Git. There's the graph structure and some tools to manipulate it. It doesn't do much to hide that.

The underlying code of the application I'm writing would be much "simpler" if I didn't have to add all kinds of features to make it easier for the user.

Also, Git is not so much a VCS application as a framework for version control.


> "from here we can state that, obviously..." He suddenly stops, slowly turns the head down, keeps mumbling "so we can obviously...". He slowly walks in the room, trying to catch the thought, then leaves the room... Some minutes pass. Then he comes back, with head up, widely open eyes and confidently continues - "Yes, this is completely obvious - so from here we can easily get the following conclusion."

I had a lecturer who did this! With the only difference being he didn't leave the room, he would just stand there speechless with a poker face and then - 0.5-1 minute later - he'd say "well, this is obvious".

SUDDENLY, during the exams he expected us to explain the obvious.


There is a good complementary story to this, of the math professor who is asked how to solve a math problem by a student. The professor pauses, then says the answer. The student asks again, "But how do you solve it?" The professor pauses again, says the answer again. When the student protests, the professor says, "I already solved it two different ways! What more do you want?"


My problem with git is that it has a simple model, with a horrible GUI on top.

For example, what does the following command do?

    git checkout a/b
I've had confused users manage to produce 3 different outcomes from this command:

* Get a clean copy of the file a/b from the current branch

* Checkout the branch b from remote a

* Checkout the local branch 'a/b'

By confusing where you can use particular types of arguments, I've found students will often end up in these situations (in particular lots seem to end up with local branches called 'remote/branchname', or files called 'remote/branchname'), which tends to lead to massive confusion.

Life would be much better if git was a more direct mapping to it's underlying model, and didn't try to be so clever about guessing what users wanted.


You asked what the following command did, and it will do plainly what you tell it to, but you're treating the fact that a/b can be anything you make it to be somehow a fault of checkout, and all because it decided to be nice and try to guess what you really want. I don't understand that line of thought.

The git documentation clearly states what happens in your scenario:

> ARGUMENT DISAMBIGUATION

> When there is only one argument given and it is not -- (e.g. "git checkout abc"), and when the argument is both a valid <tree-ish> (e.g. a branch "abc" exists) and a valid <pathspec> (e.g. a file or a directory whose name is "abc" exists), Git would usually ask you to disambiguate. Because checking out a branch is so common an operation, however, "git checkout abc" takes "abc" as a <tree-ish> in such a situation. Use git checkout -- <pathspec> if you want to checkout these paths out of the index.

See here: https://git-scm.com/docs/git-checkout#_argument_disambiguati...

If you somehow manage to purposefully name things in a confusing manner, you can tell git exactly what you want it to grab at any point in time. I don't possibly see how this is a fault of the tooling.


We might just have different points of view here.

Obviously one can read the documentation carefully and read what's going on, but in practice most users don't. Also, to be fair to users, they often don't know what they don't know -- they aren't aware they should be reading how checkout does argument disambiguation when they start getting weird error messages.

On the other hand, if git didn't allow '/' in branch names, except are a remote/branchname seperator, then we would know what '/' meant -- in practice this is what almost everyone does in practice anyway (there may be a deeper issue here I'm not aware of).

Similarly, if git didn't have commands which could take either a <tree-ish> or a <pathspec>, say have "checkout-file" (that's an awful name, but I'm sure we can find a better one), then there would be no need to have this special bit of documentation, and describe to people how to get around the issue.

My experience of teaching is that git guessing what people want makes learning git harder, as they have to learn what are the fundamentals, and what is git being "helpful".


Yep there's a lot of best practices you learn after using git for a while that is not obvious initially, like not using '/' in branch name (though, I used to have a coworker who always named branches like 'fix/something' or 'feat/something' -- well at least there was a pattern there).

I also don't use most of the git commands directly, I have a bazillion of aliases that are shorter and/or more intuitive.

To be honest, there were some changes for the better in the CLI. For instance 'git push' no longer defaults to the crazy 'matching' behavior, but 'simple' instead.

I guess the problem is perhaps that most of the time, people get used to the quirks and don't report them (maybe I'm mistaken).

In fact, if git bug tracker was hosted on GitHub, I'd probably be more active in reporting and discussing things. I'm not an old school mailing list kind of guy I guess, and maybe not only me (but I believe many git maintainers would say, it's a feature that barrier of entry is not low).


I always use '/' in the branch name and have never had any issues. Can you explain why this would be an issue?


The only issue I am aware of is that beginners often assume, based on basically every tutorial, that / has a special meaning, it is used to denote remote/branchname.


To be fair, issues like this are really only UI issues with some git commands, not necessarily git as a whole. The GP post was probably lamenting a much deeper issue with the design of git.


Mercurial bookmarks are equivalent to git branches, but Mercurial branches have no equivalent in git. In Mercurial, branches give you a way to track the branches a commit is a part of which is good for long-running branches (I think of things like master, maybe a long running refactor or major feature branch) while bookmarks are great for the more normal workflow of small, focused, feature branching. Neither of those are designed to cover a gap in the core design, they are a _feature_ of the core design that git doesn't even have.


>branches give you a way to track the branches a commit is a part of which is good for long-running branches

I think you have a slight misunderstanding on the differences between git and mercurial, as git absolutely allows you to do this. Mercurial tends to track this information in a way where it actually limits telling you what branches a commit is contained in. Git will tell you straight up which branches lead back to a commit (i.e., being contained in them). Mercurial tends to only give you immediate, direct ancestors, any kind of complicated history and Mercurial can't be bothered to actually to dive in and tell you what branches a commit is really apart of.

That seems to be strangely counter-intuitive for "long running branches."

Git doesn't need an equivalent of Mercurial branches and bookmarks, because git branches do everything both of those mercurial features do and more, in a far more lightweight and efficient manner contained in a clean, singular feature.


> Git doesn't need an equivalent of Mercurial branches and bookmarks, because git branches do everything both of those mercurial features do and more, in a far more lightweight and efficient manner contained in a clean, singular feature.

Not quite everything. Since Mercurial branch names are baked into the commit, if you wanted to know which branch a commit was originally part of, you can find out.

Git does not support this. If two branches have parent commits in common, it technically belongs to both branches.

There is a valid conversation to be had on if this feature is actually necessary or makes sense in the context of a DVCS, but git branches are not a full substitute for Mercurial branches.


> If two branches have parent commits in common, it technically belongs to both branches.

It belongs to both branches as well in Mercurial, it just hides that information from you. An astoundingly bad idea, no? I'm not sure how mercurial hiding information from you is a "feature" in any sense of the word.


Hiding or encapsulating information is arguably part of the very nature of an abstraction; the CLIs provided by git and Mercurial could be considered an abstraction of the implementation details of the respective technologies.

As such, I fully expect each tool to hide some amount of information so that I don't have to think about the details.


There's no easy quick way to represent the actual state of the commit. It's far easier in git because it's the only way to do it. Furthermore, then information being "encapsulated" can actually become stale or misleading in Mercurial.


Mercurial records in every commit, that branch it was made. It is part of it's identity. That is what the parent is talking about. Git does not do this. Because git does not have this concept of named branches.

In other words, Mercurial has feature branches, while git has developer branches. This gives much more possible workflows in case of Mercurial.

>Mercurial tends to only give you immediate, direct ancestors, any kind of complicated history and Mercurial can't be bothered to actually to dive in and tell you what branches a commit is really apart of...

http://stackoverflow.com/questions/7166011/mercurial-find-al...

Is that what you are talking about?

Mercurial contains vastly more querying capabilities in the form of revsets. No such thing exists for Git.

If you go head to head with git vs mercurial, git will loose pathetically.


>Git does not do this. Because git does not have this concept of named branches.

It doesn't pre-bake the information in the commit, because it's entirely useless information to bake into a commit; and even in the case of Mercurial can paint the wrong picture about the nature of a commit given branches that it's on.

>This gives much more possible workflows in case of Mercurial.

That is the exact opposite of what it gives you. I'm not even sure how you possibly arrived at that conclusion.

>Mercurial contains vastly more querying capabilities in the form of revsets.

Git doesn't need a query language, because you can literally do everything revsets will give you with git log and then maybe some very elementary bash script knowledge. You are literally arguing that Mercurial having its own arbitrary DSL is somehow better than git being able to seamlessly use popular tooling with conventional command line syntax; which seems to be at odds with the whole "mercurial is easier to use." I take extreme issue with your claim that Mercurial has "vastly" more querying capabilities and then you not even give one measly example.


>because it's entirely useless information to bake into a commit;

I have found it very useful in untangling a complex history. You might not see the value in it becuase git does not care to maintain a truthful history, but promotes building a "clean" history. It makes sense to do that if you are maintaing somethign like linux kernal. But for smaller projects, maintaining a truthful history is much more valuable.

So I would say that it is extremely valuable information in the context of Mercurial.

And there are other version control systems that follow similar model. Take a look at the '3.3 Branches' heading in another fantastic version control system called 'Fossil' here [1].

>That is the exact opposite of what it gives you. I'm not even sure how you possibly arrived at that conclusion.

Well, Mercurial supports git's branching model and a lot of others. I am not sure how that is not clear.

>Git doesn't need a query language...

Of course. It is not meant to be used by mere mortals..

>because you can literally do everything revsets will give you with git log ...

Are you seriously saying that using command line flags is more powerful and easier than using a query language that lets you use arbitrarily expressions to query a data set?

> I take extreme issue with your claim that Mercurial has "vastly" more querying capabilities and then you not even give one measly example.

Checkout the link I mentioned in my earlier comment.

This is the manual page for revsets [2]. Please take a look.

[1] http://www.fossil-scm.org/fossil/doc/trunk:2012-01-01/www/fo...

[2] https://www.mercurial-scm.org/repo/hg/help/revsets


>But for smaller projects, maintaining a truthful history is much more valuable.

Elaborate.

>Mercurial supports git's branching model and a lot of others.

Except, it doesn't completely.

>Are you seriously saying that using command line flags is more powerful and easier than using a query language that lets you use arbitrarily expressions to query a data set?

Yes, because command line flags are ubiquitous in nearly every single tool, versus an arbitrary DSL that has no convention behind it, or can be easily parsed by other tools in the same ecosystem.

> Please take a look.

You seem to be under the impression that I have not or do not use Mercurial. You would be mistaken. Both of those pages do not lend support to your claim that the ability to "query" (with or without a DSL) the history graph is somehow superior in Mercurial. They merely document the feature, but do not draw any meaningful comparisons highlighting what it can do that git log or even git rev-list (which git log uses) can't.


> Elaborate

For example, to answer questions like "What feature was this commit part of, originally". "How and where did the merges happened?". To answer these questions months after the merges happened, even after you did't think that you would need to answer these questions, something like the workflows mercurial is essential.

>Except, it doesn't completely.

Elaborate?

>Yes, because command line flags are ubiquitous in nearly every single tool

Ok. But that does not mean that it is powerful enough and can be a replacement for or better than a proper query laguage..

> arbitrary DSL that has no convention behind it

What convention? I am not getting you.

>can be easily parsed by other tools in the same ecosystem.

Parse what exactly?

>Both of those pages do not lend support to your claim that the ability to "query" (with or without a DSL) the history graph is somehow superior in Mercurial. They merely document the feature, but do not draw any meaningful comparisons highlighting what it can do that git log or even git rev-list (which git log uses) can't.

Oh it does support it plenty. Take a look at the vocabulary supported by revsets in form of intuitive and easy to remember predicates. I don't think you are really impartial if you are not convinced by it.


>to answer questions like "What feature was this commit part of, originally"

Neither system will answer that. If you're relying on branches to tell you what feature sets changes belong to, you should be adding that to your commits.

>"How and where did the merges happened?"

Git will do this faster and in a more correct manner. In a complicated history graph, Mercurial will actually hide information from you if you try to query it and sometimes even mislead you. I'm starting to think you haven't used either system extensively.

>Parse what exactly?

Arguments and output.

>Oh it does support it plenty.

It does not. If you can't give an example, you can just admit that you don't know what you're talking about.


>Neither system will answer that....

I am not sure what you are talking about. Every change set in Mercurial contain the branch in which it was made. Even after a merge, there is a clear distinction about the commits made in a certain branch.

I think you might be thinking of rebased change sets. In that case, you would be right.

>Git will do this faster and in a more correct manner..

Please show an example. I would also like to see an instance where Mercurial hiding information from you and giving misleading answers to your queries.

>Arguments and output.

But it is supposed to be used by people. So it should be first human friendly. And there is nothing stopping you from parsing output of mercurial commands. And what is the use case of parsing arguments? Why did you think so? Mercurial has even a template feature letting you format the output in any way you want. I am not sure, it seems to me that you are not making a whole lot of sense..

>If you can't give an example, you can just admit that you don't know what you're talking about.

There are some examples at the bottom of the revset page I linked. Knock yourself out. And do share some examples of your claims, because your last commits contained enough stuff to doubt your experience..(stuff about conventions and DSLs, what was that again?)


> I would also like to see an instance where Mercurial hiding information from you and giving misleading answers to your queries.

A branch with two heads. Two branches that have the same name. Which commit came from where? What happens if that branch was merged into the other? Or what happens if only one got merged into a "mainline" branch, while the other one was reverted else where. It's useless information at best, and misleading at worse.

>But it is supposed to be used by people. So it should be first human friendly.

You're going to claim a DSL that you have to research is somehow easier to use than simple command line arguments that have decades of convention behind them? Odd.

Git allows you to format output as well. Not sure why you felt the need to bring that up. Again, unless you've extensively used both systems I'm not sure why you feel the need to argue because it's making you look foolish.

>There are some examples at the bottom of the revset page I linked.

And absolutely none of them help your argument.


> It's useless information at best, and misleading at worse.

It seems useless to you because you see it from a git viewpoint. It is clear when you say that "Two branches that have the same name". It is not "two branches", but one branch with two heads. In Mercurial, a Branch is a set of commits. That view is incompatible with the thing that git call "branches".

If you think about it, Mercurial's implementation of a Branch is closer to the idea of a "Branch". As I told earlier, Mercurial branches are "Feature" branches". I am not sure if you have gone through the fossil doc page I linked earlier. When you see it like that, it makes complete sense that a Branch can have any number of heads. Say, the second head containing a different implementation of the same feature.

(God I miss Mercurial)

>Which commit came from where? What happens if that branch was merged into the other? Or what happens if only one got merged into a "mainline" branch, while the other one was reverted else where. It's useless information at best, and misleading at worse.

These questions are the result of trying to make sense of Mercurial branches in a GIt way..

>what happens if only one got merged into a "mainline" branch, while the other one was reverted else where.

Again, this question is a result of you seeing mercurial branches in a git way. Because git define a branch as the set of commits starting from a "head", the idea of merging only one of the heads does not make sense to you.

But you can do the same with git, right. You can move back couple of commits from a head and create a new head by starting committing from there. Only that in git, the previous head would be hidden. And you will have to go to the reflog to dig them up. But in Mercurial, things are much clearer and exposed (contrary to your accusation of it hiding and misleading).

So again, it feels misleading to you because it is different from git. It is very consistent in conforming to its on model.

>You're going to claim a DSL that you have to research is somehow easier to use than simple command line arguments that have decades of convention behind them? Odd.

I am not at all getting you here. "command line arguments that have decades of convention"? What exactly does that mean? And what is the thing about "a DSL that you have to research"?. You don't have to look up command line arguments of git? And you call git's command line arguments simple?

>Again, unless you've extensively used both systems I'm not sure why you feel the need to argue because it's making you look foolish.

I didn't claim that git does not allow you to format the output, but just that Mercurial allows you to do that so that your argument about easily parseable output is moot.


Could you maybe specify better how this is implemented in hg so that I can understand why it would be better than:

    git branch --contains <commit>


When you make the commit, hg records in the commit which branch you were on when you made it. It becomes a permanent part of the commit. Regardless of whether you later merge or even delete that branch, the association between that branch and that commit is still there.

I personally don't understand the use case, and prefer git's way of handling things, but I don't rule out that other people find it useful.


One use case is given branch X, tell me what the branch looked like N commits in the past. Git cannot tell you this because all parent commits are equal. DVCS workflows tend towards lots of short-lived branches where it is less useful (which is why hg has bookmarks).

It can also just simplify certain things. I can tell by checking if a commit is reachable from e.g. the v1.2 bugfix branch but not from master that the commit was post the 1.2.0 release to fix a bug.

With hg branches you can just see that the commit was made the the v1.2 bugfix branch. This is very minor, but my experience with hg is that there are dozens of these minor niceties that are why a lot of hg users are still around despite git having clearly won the popularity contest.


>One use case is given branch X, tell me what the branch looked like N commits in the past.

What am I not understanding here? You definitely can go N commits in the past on each branch, and even any commit. And if you rewrite history you can even use the reflog to really tell what the branch was like (as long as it hasn't been cleaned out).


    ┌─────┐◀──────── master
    │Merge│◀──────── bugfix
    └▲───▲┘
     │   │
     │   │
     │  ┌─┐
     │  │B│
     │  └▲┘
    ┌─┐  │
    │A│  │
    └▲┘  │
     └───┤
         │
    ┌────────┐
    │Ancestor│
    └────────┘
Which branch was commit `B` made on? What did the `bugfix` branch look like one commit ago?


Nice use of Unicode! Do you have a tool to help you construct a diagram like this?


If you were in master when you merged bugfix in ("git merge bugfix"), then you can

  git cat-file -p master
and see which commit, A or B, is listed as the first parent. This belongs to the master.


> Which branch was commit `B` made on

You can do some basic heuristics to figure it out, but I'm not sure what the point of knowing this is.

>What did the `bugfix` branch look like one commit ago?

`git checkout bugfix; git log bugfix^1`


In the case of merges, how would you tell which parent to look at? Branches might have been deleted, moved, or merged.

> And if you rewrite history you can even use the reflog to really tell what the branch was like (as long as it hasn't been cleaned out).

The reflog is not moved across remotes, is it? If I make a fresh clone of a repository, that doesn't tell me what the branch was like a year ago.


You're right, it's not moved across remotes. I'm just confused to why the information would ever be needed. It seems to not have any real use case. You can recreate a branch any where at any point in the history, why would you care what commit a branch originally came from? It seems like a solution in search of a problem. Or maybe even a solution to a problem that shouldn't need solving in the first place!

>If I make a fresh clone of a repository, that doesn't tell me what the branch was like a year ago.

This isn't true with Mercurial either. A lot can happen in a year, and it might even make the information misleading (having similar named branches, history deletion, etc). It's useless at best and misleading at worst.


"This commit has a bad commit message. Why did I commit it? Oh, it's on the branch add-search-functionality."

I find that having a branch name that was the sole branch name when the code was made gives context to the commit; why it was made and what its purpose was. Being reachable from a branch pointer doesn't give that same context. Yes, commit messages should handle this. But I find they don't.

> It's useless at best and misleading at worst.

This has not been my experience. I haven't found a great need for "what's the whole state a year ago"; more so "what was the context around this commit", which I think a mercurial-style branch name answers.


I'm sorry, in what practice are you in where your commit messages are somehow so lackluster that a branch name (not even a PR!) can give you more information about why something is being done?

And to make sure no one responds with some silly "just because you don't have a use for it, doesn't mean don't have their uses for it": I get what you're trying to say. I'm really just not buying it as an actual use case. If your commit message isn't sufficient enough to explain the purpose of the commit (ticket numbers, explanation, etc), it doesn't get approved. If you're relying on a <20 character branch name to give you sufficient context about a commit a year later, I simply have no words.

>which I think a mercurial-style branch name answers.

I find that extremely suspect.


> If your commit message isn't sufficient enough to explain the purpose of the commit (ticket numbers, explanation, etc), it doesn't get approved.

I'm glad this is the case where you work and develop. I have never worked at a company where this is the case. I'm also not perfect about commit messages in my personal code. The codebase I'm currently working on has recent commits with description "review", "add addressDto" and "post rebase fix".

> >which I think a mercurial-style branch name answers.

> I find that extremely suspect.

Ok. If I see "add addressDto" as a part of the branch "google-geocoding", that tells me the context. If I see it as part of "refactor-to-use-hibernate", that also tells me something useful.


>The codebase I'm currently working on has recent commits with description "review", "add addressDto" and "post rebase fix".

I guess what I don't get, is that if you have people doing commit messages like that, how can you possibly expect them to appropriately name a branch which most likely stores far less characters.


Far too often the commit message says "what" while the branch name says "why."

Just recently I had to triage a recently discovered bug whose symptoms disappeared about 4 years ago to determine if the bug was fixed or just masked. This was code that I was completely unfamiliar with because the other engineers that might have looked at it were otherwise indisposed working on things that were known for sure to be issues.

The "what" told me the specific change that masked the bug and the "why" informed me of the feature that this supported. That allowed me to generate a new test-case that showed up in the current version. Without both pieces of information I would likely have had to spend a couple of hours inspecting code changes to do the same.


If you can't trust your developers to write acceptable commit messages, why are you trusting them to write code?


Because you're less in the nitty-gritty when naming a branch, so you're more likely to name it with something referencing the large feature you're working on.


I work with two codebases with over 200k commits and over 10k branches each. Sometimes the branch names are useless. Sometimes the commit messages are poor. Often knowing one helps provide more context for the other.

Believe it or not, there were times in the last 20 years when there was insufficient review of commit messages!


It's sometimes very useful, but not that often. It's not great for short lived feature branches. It's for long-term branches. If you don't need those (and most often you do not): great, your life is (relatively) simple; don't over-complicate it. You don't buy the use-case, because the situation is not that common or desirable. But once you get in a situation where you really do need multiple long-term branches developed in parallel, you might be happy to have a tool that helps untangle the web of merges somewhat.


>It's for long-term branches.

Please elaborate how this helps you in long-term branches, instead of just assuming long-term branches aren't something most people deal with on a daily basis.

>you might be happy to have a tool that helps untangle the web of merges somewhat.

This has no relation to long-term branches, this happens with any kind of normal history, and even shared history between repositories (which is a far messier thing to untangle). Yet this feature is unneeded, because the information can be correctly found within git in an accurate and not misleading fashion.


> branches give you a way to track the branches a commit is a part of which is good for long-running branches (I think of things like master, maybe a long running refactor or major feature branch)

If you always merge "from the right direction", you can follow the first parent line in git and reconstruct which parent is in the master branch (or in the "heavier" branch in general) and which isn't.

In more complicated situations, Mercurial named branches (commit forever carries the branch name) can be helpful. But you can get pretty far with git, too.


> most commands or command flags simply help the user do something in an automated fashion that you could do by typing each specific command out (i.e., git pull --rebase)

A tangent perhaps, but would you mind expanding on this? I use `git pull --rebase` frequently, and I'm not sure how this fits into what you described. Is it the specific command, or the automated shortcut? And what's the counterpart?

Just trying to check my mental model.


"git pull" is just a shortcut for running "git fetch" and then merging (or rebasing) the current branch to its upstream.

IMO this is a stumbling block for a lot of people new to Git -- for example it covers up the fact that "remote" branches are a separate reference ("master" and "origin/master" are not the same branch!).


"remote" branches are called remote-trackimg branches. And yes, it's very confusing. Especially when git status says "up to date with origin/master", but pulls down loads of stuff when you pull...


From the "git-pull" man page:

> Incorporates changes from a remote repository into the current branch. In its default mode, git pull is shorthand for git fetch followed by git merge FETCH_HEAD.

> More precisely, git pull runs git fetch with the given parameters and calls git merge to merge the retrieved branch heads into the current branch. With --rebase, it runs git rebase instead of git merge.


I had a comment written up, but I decided to test my claim in my original post about a "litany of literature", and sure enough this has been documented elsewhere:

http://gitolite.com/git-pull--rebase

I searched for "how does git pull --rebase work"




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: