schacon / hg-git

mercurial to git bridge, pushed to directly from the hg-git plugin in Hg
GNU General Public License v2.0
620 stars 72 forks source link

Prune branches that have been deleted remotely #326

Open Eibwen opened 6 years ago

Eibwen commented 6 years ago

I'm using hg-git in an environment that most people are using git and is hosted on gitlab, and therefore are creating hundreds of branches.
I don't see any tools built into hg-git that helps prune those branches once the author merges/deletes them, instead my local hg repo has those hundreds of obsolete bookmarks.

Do any of these commands/methods work for an hg-git repo? https://stackoverflow.com/a/3184742/356218

Or am i using hg-git incorrectly and I should have a repo that is NOT a working directory that is the hg-git repo, then pull with hg from that, and use that hg-only repo as my working directory, then sync the hg-git repo when I need to contribute to the git repo?

In the mean time I have built a C# script that uses hg outgoing to find what can be manually pruned, but that does not seem like a very safe nor efficient method of doing this

tamsky commented 5 years ago

Don't recall where I got this, but I definitely didn't write it:

[alias]
nukebookmarks = !$HG bookmarks | tr -d '*' | tr -s ' ' | cut -d ' ' -f 2 | xargs $HG bookmark -d

But this is definitely a local-only strategy... it does not try to reconcile remote branches.

manueljacob commented 5 years ago

By default, all shared history is immutable by default in Mercurial. However there is the evolve extension, enabling to modify history, including pruning changesets: https://www.mercurial-scm.org/doc/evolution/user-guide.html#example-4-prune-an-unwanted-changeset

For this, is has to be ensured that all changesets stay in draft phase. Also hg-git needs a way to synthesize obsolescence markers if a branch disappears from a remote repository. I don't know if any of this is implemented.

Sorry that this doesn't help you right away. For now, a mix of setting all your commits to draft by default (look for "phase" in README), using evolve (https://www.mercurial-scm.org/doc/evolution/) and manually removing the removed-from-Git commits could work for you.

tamsky commented 5 years ago

Or am i using hg-git incorrectly and I should have a repo that is NOT a working directory that is the hg-git repo, then pull with hg from that, and use that hg-only repo as my working directory, then sync the hg-git repo when I need to contribute to the git repo?

I've set myself up with a "similar" setup, but for other reasons -- I offer it here for others that might benefit from this setup:

I work with a very large git repo, with a rapidly growing commit count (currently 110k+), 100k+ named tags and 1k+ named branches.

I've settled on the following workflow, which keeps my hg-git client light, and keeps those named tags out of my hg client (that many named tags makes dulwich significantly slower).

I have two local clones, one hg+git based, and one git only. In my hg+git repo, I pull/push from/to the git cloned repo. In my local git repo, I locally delete all tags, and then configure .git/config:

[remote "origin"]
     url = git@github.com:org_name/repo_name
     tagOpt = --no-tags
     fetch = +refs/heads/master:refs/remotes/origin/master
     fetch = +refs/heads/tamsky/*:refs/remotes/origin/tamsky/*

I compose my changes in hg, create a bookmark starting with text tamsky/, and then commit. I then hg push -r ., which pushes to the local git checkout, which creates a named local branch in git. I can then use git push origin tamsky/<branchname> to push that one branch. I use git fetch --prune ; git pull to remove local branches that are missing in the "origin". I use the hg nukebookmarks alias, followed by hg pull to sync current, and purge deleted branches.

Sometimes git gets confused (when the upstream and local branches diverge), and I need to git branch -D a named branch, and then repeat the git fetch->hg nuke; hg pull operation, but it mostly works without much thought.