Hacker News new | past | comments | ask | show | jobs | submit login

I think git and hg are both pretty bad in different ways.

Both have pretty terrible UI but so long as one uses magit, git comes out way on top.

The data models are different and suffer different problems. A main issue with git is that it is stupid about file copies and renames. An issue with hg is that it doesn’t work well with long running forked histories (i.e. like git branches) because it stores the set of revisions of a file as a list of blocks of “complete file” or “diff from previous version in this list”

Both have scaling problems to large repos and algorithm/data structure problems which cause too many operations to be e.g. O(size of history) at least. I suppose this is better than Darcs’ model of “commit on Friday and hopefully it will be done by Monday.” If hg we’re naturally good at scaling than e.g. Facebook wouldn’t be putting so much effort into trying to make it scale (e.g. using inotify instead of looking throughout the tree for changes (which I think shouldn’t count as any vcs gains from this), having a mergeless history, rewriting a ton of hg in rust (git was always partly in C and there is now also libgit2)).

The thing that makes me most sad about hg is the lack of a really good (ie good and emacs-based) ui.

I’m all for different vc systems being developed and I think it would be good to see some real innovation potentially break up the current git-hg hegemony.

I think there are lots of good things about fossil (e.g. using an actual database that is going to scale well and avoid data corruption instead of using a specialised data structure that is hard to change and likely not so corruption resistant or battle tested or scalable but maybe let’s your data structure be “faster” for certain operations)

Another interesting vc system being developed at the moment is pijul which can be simply described as “like darcs but fast and more likely to be correct”. It feels a bit like it’s fitting in with the current trend of CRDTs, although it’s core data structure is not a CRDT as that would imply that all merges have some deterministic resolution (ie merge conflicts do not happen) and that is not the case, instead files are allowed to be merged into a first-class conflicted state which can then be resolved by later patches.




> A main issue with git is that it is stupid about file copies and renames.

Could you elaborate on this? As far as I know, file copies and renames will still use the same blob, but the tree referencing the blob can reference it using a different path in the case of a rename or reference it more than once in the case of a copy.


If you tell hg to rename a file, e.g. hg mv foo bar, it will generate a patch which essentially just says “foo was renamed to bar”, and when you look at the diff the only thing that has changed is the name.

If you merge this with a patch that changed foo then hg will do something sensible (ie either merge the changes into bar or give a merge conflict).

Git has no first-class concept of file name changes. Instead it tries to use heuristics to spot renames and sometimes they work and sometimes they won’t. Maybe if you merge a patch renaming foo to bar with one that changes foo the second patch will be applied to bar, but maybe it will behave as if you are merging changes to foo with deletion of foo.

Merging is already hard, dangerous, and non associative. The danger is less that you get lots of annoying merge conflicts than that you don’t get a merge conflict when you should (and therefore you risk accidentally changing the meaning of the merged files without knowing), e.g. if you merge “rename foo to bar” with “delete foo” and git didn’t spot the move then the merge might leave bar untouched when really there should be a conflict between keeping/deleting bar. Having wrong merges happen automatically can be a big risk when software is supposed to be very reliable.


"Git has no first-class concept of file name changes. Instead it tries to use heuristics to spot renames and sometimes they work and sometimes they won't."

Git has the "mv" command. If you "git mv" a file, why would git have to guess or use heuristics to figure out that the file was renamed?


As the Git FAQ [0] says:

> Git has a rename command git mv, but that is just for convenience. The effect is indistinguishable from removing the file and adding another with different name and the same content.

git diff, merge, and related tools have heuristics for detecting file moves (off by default, turned on with e.g. git diff -M) but they tend to break if a file is both moved and modified in the same commit.

[0] https://git.wiki.kernel.org/index.php/GitFaq#Why_does_Git_no...


Yeah exactly why I always commit renames right away and atomically. I mean it's a _relatively_ rare thing and when I have to do it I just want to make and record the change and then move on. Renaming and then modifying a file in the same commit is slightly sloppy imo. Not to say that the tool couldn't be doing a better job.


Because git stores sets of files. If you move a file and make a new commit, it's just a new set of files which says "this old set is my parent". There is nothing in there about the renamed file.


Still, at the point you do a "git mv", it can't be said that git doesn't know you renamed a file. It knows.

In fact, after a "git mv foo bar", if you do a "git status", you'll see:

  On branch master
  Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)
  
          renamed:    foo -> bar
If git chooses afterwards to discard that information and do nothing with that knowledge, that's a separate problem.


I don't know enough about Git internals in this regard, but it's possible that in fact the index is just being compared to HEAD to infer that information. Index has a file called "bar" and none called "foo". HEAD is vice versa.


Yes, Git has "mv". Git also detect file rename. I'm not aware of the method though. I'm talking based on experience. I renamed some file normally, without Git. When I checked the `git status`, Git says it was renamed.




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

Search: