Wanted: Git Help for HIG

Way back when we imported the HIG into gnome-devel-docs, I had a hig-devel branch set up for Calum’s work on the next generation of the HIG.  Except branches in SVN aren’t really branches; they’re just separate directories we copy into.  And I very stupidly took advantage of this fact by making the hig-devel “branch” be just a mirror of the hig/C directory of gnome-devel-docs/trunk.

My fault completely.  I shouldn’t have done that.

Now I’m trying to find a way to fix this branch in git.  If I just merge master into hig-devel, it basically blows everything away.  Git has no way of knowing that it should apply changes from some completely unrelated files that don’t exist in master.

Worst case scenario, I suppose I just do the merge, copy the hig-devel versions of all the files in, and commit.  Anybody have any ideas on how to do this in a way that preserves some history?

11 thoughts on “Wanted: Git Help for HIG”

  1. git filter-branch can do all sorts of magic in cases like this, although its a bit tricky to use.

    I think you can do this if you put a full checkout of the branch point, sans the hig/C directory somewhere, then you run something like:

    git filter-branch –tree-filter “mkdir hig/C; mv * hig/C; cp -r /checkout/* .” hig-devel

    But this is completely untested. Do your testing in a checkout that contains no important info.

  2. I think what you are looking for is git filter-branch –subdirectory-filter []. You can make a new branch with the full history, then apply this to it, which should result in a separate branch with the history that touched only that subdirectory. Let me know if it works out (because I could have used this yesterday also, but was to lazy to look it up :))

  3. Import with git-svn or something, which is aware of svn’s directory stupidity, and you can then use git-filter-branch to construct a more sane set of history along that branch, with fixed filenames etc. Once you’ve done that, you should be able to do a clean merge.

  4. I think you want a subtree merge, but it gets a bit more complex by originating from svn, especially if you want to preserve the original branch point.

    Google for “giit subtree merge”

  5. As daniels said, you can use git-filter-branch (you already have the history in git.gnome.org so no need to use git-svn).

    Basically you need to do three things:

    1) Reparent the first commit in the branch (using a graft file)
    2) Move all the files to the corresponding place (there is an exemple in the git filter-branch man page)
    3) Add all the other files (maybe with git-read-tree .

    Another option could be export all the commits in the branch with git format-patch, fix the paths, and apply them with ‘git am’.

    At the end the only difference between the two should be the commit date, it is preserved with git filter-branch while with ‘git am’ it would be the present date (I think in the last git release or in the master branch there is a flag to use the author date as committer date).

    HTH,
    Santi

  6. So basically you have two independent pieces of work in two git branches, right?

    I’m not sure how it worked, but it’s definitely possible — the btrfs merge in the Linux kernel did that. I can try to dig it up, send me an email.

  7. I made two experimental local branches, first starting from the hig-devel branch, re-writing it to move all the files to hig/C/ like so:

    git filter-branch –tree-filter ‘mkdir -p hig/C; ls | grep -v “^hig$” | xargs -ifoo mv foo hig/C/’ HEAD

    Then I did a “git merge master” to merge in the changes. There were conflicts, so I opted for the branch’s version with “git checkout –ours” (and then the conflicting files). I did a “git add” for those conflicting files, and then a “git commit”.

    An option is to rebase the new version of the branch off of master with “git rebase master”, to move the commits above the trunk. It’s a bit of a mess, and you’ll get conflicts along the way. I did the “checkout –ours” thing for the files each step of the way, and then a “git rebase –continue” (after adding the conflicting files). After a while of doing that, it was finally finished. For good measure, I did a “git merge –squash” (and then the original branch), since there were so many conflicts.

    Neither is perfect, but it moves the files to where they are supposed to be and they’re both attempts to preserve much of the history.

    I can publish the two versions of the changed branches somewhere (even to the official repository) if you’d like to inspect them… just let me know.

    If you do decide to make a modified version of the branch an official one, you would have to do a force push if you keep the same name, and make sure everyone else who checked it out does a force pull. I suggest just using a different name for the branch and removing the original “hig-devel”, to spare possible confusion.

  8. (Note: The typewriter single and double quote marks got WordPressified into typographical marks.)

  9. Maybe the subtree merge strategy of git is what you’re looking for? Check `man git-branch` which has a very brief description. I haven’t had the need to use it yet, but it sounds like it might be just what you need.

  10. It’s going to be pretty hard to recover that branch. Not only is there the difference of tree structure, but a) the initial commit of the branch doesn’t have the right parent commit, so it looks unrelated to history prior to 2007 b) older version in the branch are missing files *within* hig/C; the files appear only when first modified.

    With a fair bit of work, git-filter-branch –parent-filter and git-filter-branch –tree-filter could be used to rewrite the branch “as it should have been” by using the right parent commit, moving stuff to the subdir, and adding missing files. If you decide to go that route and get something you like, find me on IRC for help in pushing the rewritten branch to git.gnome.org.

    However, I don’t see much useful history on that branch, so maybe it isn’t worth it.

  11. Yeah, I wouldn’t worry too much about preserving history, tbh. At this stage, I think it’s not unlikely that the current devel version of the HIG will be scrapped and rewritten for 3.0 anyway… or perhaps that’s just wishful thinking 🙂

Comments are closed.

Creative Commons Attribution 3.0 United States
This work by Shaun McCance is licensed under a Creative Commons Attribution 3.0 United States.