Alembic: how to downgrade an entire branch? - sqlalchemy

Say this is my graph of alembic versions:
a -> b -> c -> d
\> e -> f
i'm interested in rolling back e and f but not c and d
so the issue is:
alembic downgrade takes an argument that represents the target revision (rather than the revision to be rolled back)
alembic downgrade e will correctly downgrade from f to e
alembic downgrade -1, so far as I can tell, can technically roll back the head of either branch.
I can't seem to do alembic downgrade b to roll back e and f without also rolling back c and d
Is the thing I'm trying to do possible with alembic?

UPDATE: It turns out this has been an open issue since 2017.
https://github.com/sqlalchemy/alembic/issues/464
My solution, for posterity, is to make a new revision g that will undo the changes in e and f so I basically get to work from the state of b.

Related

revision errors in feauture branches while converting from cvs to mercurial

We are converting the cvs repository which has two branches (one is the MAIN and the other is the FEATURE,rest all can be ignored) into a mercurial repository.
We are using the inbuilt tool convert with the following command.
hg convert cvs_source_dir hg_new
where cvs_source_dir = Updated Directory with only Feauture branch changes from CVS.
hg_new= new name of mercurial repository .
After converting ,the hg_new repo has all History data from CVS.
when we did an hg update it points to MAIN branch code .
And if we update it to FEATURE to get the code from FEAUTURE branch as per CVS , by using
hg update FEAUTURE , all the files which dont have a revision in the FEAUTURE branch is getting deleted.
How can this be solved?
If I understand correctly, branch FEATURE doesn't have some files that exist in branch MAIN, so when you hg up to branch FEATURE, these files are missing.
I think it is a feature that hg up brings your working directory into the status when you committed (-c will check the uncommitted changes), so the files that do not exist in branch FEATURE will gone.
This post shows a method to get the file you want from another branch. If you have a list of files, iterate the list and get every file to your current working directory.
[Updated]
A graph to show how to make it right:
(1) your current status
A -- B -- C -- D (MAIN)
\
- E -- F -- G (FEATURE, missing files)
(2) step 1:
A -- B -- C -- D (MAIN)
\
- E -- F -- G (FEATURE, missing files)
\
-H (FEATURE, a head adding all missing files from A)
(3) step 2:
A -- B -- C -- D (MAIN)
\
- H - (rebase) - E' -- F' -- G' (FEATURE, missing files)

Merge problems in mercurial because of wrong merge base: what's happening?

I have a repository in which two revisions (14321 and 14319) share a parent (14318) - both changesets are direct children of 14318. Nevertheless, the revision set query ancestor(14321, 14319) does not return 14318, but instead returns a much older changeset. What's happening?
Screenshot in TortoiseHg:
Background: I encountered odd merge conflicts recently that turned out to be caused by mercurial trying to re-apply changes that had already been merged. I was able to track it down to an odd choice of merge base which caused both heads to include the same changes - but I don't understand why this happened and how I can prevent it in the future (I chose a DVCS partly to avoid these kinds of problems in the first place...)
The picture shows there are not one but two common ancestors. So, it looks like a criss-cross merge case where merge problems arise from chosing one or another common ancestor.
References:
https://bz.mercurial-scm.org/show_bug.cgi?id=1327#c18
http://www.gelato.unsw.edu.au/archives/git/0504/2279.html
http://wiki.vestasys.org/MergingFuture/Food4Thought/TrickyCases
http://revctrl.org/CrissCrossMerge?action=recall&rev=11
There is a proposal for a new merge algorithm (https://www.mercurial-scm.org/wiki/ConsensusMerge). However, since Mercurial's 2.3 sprint this topic is stuck.
To reduce this kind of problem, I suggest you to estabilish a client-server topology, so that developers only merge with the official repository. Maybe rebase could help also.
A criss-cross merge is something like this:
B --- D
/ \ / \
/ \ / \
A X F
\ / \ /
\ / \ /
C --- E
In your case, it was:
B
-----------o---- } stable/production
C \ \ F
------o------o---\------o } default
\ D \ /
-----------o--- } feature
E
A = ?
B = 14318
C = 14294
D = 14319
E = 14321
F = ?
To produce F, there are two possible circuits: B-D-E-F and C-D-E-F. Mercurial has chosen the latter.
You could have avoided the criss-cross if you haven't merged production and feature branches.
The hotfix could have been propagated to the feature branch via the default branch. The log would be:
B
-----------o } stable/production
C \ F
------o------o------o } default
\ D \ /
-------o--- } feature
E
For incorrect base detection in case of common ancestor of mergesets one weak point is known:
it can be wrong if any of mergesets contains unrelated to merge edit
I guess, that the ancestor is 14294. Since both of your new commits are merges, you now have more than one ancestor, which makes the choice ambiguous.
Unfortunately, there is no way to tell mercurial which of the potential ancestors to use.

Mercurial Merge of Two Named Branches: Working Directory Has No Ancestor

I have two named branches, SPRINT_009 and SPRINT_010. Some changesets have been committed to SPRINT_009 that I would like to merge into SPRINT_010. I was able to merge the changesets from branch_one back into default without any trouble. I am having problems merging the changesets from branch_one into branch_two.
default A -- B -- C -- G -- H -- I -- J -- K -- L -- N -- O -- P
\ \ /
SPRINT_009 D -- E -- F ----------------- ---------- ----------
\
SPRINT_010 M
Here are the commands I am using:
hg update branch_two
hg merge branch_one
However I get the following message:
abort: merging with a working directory ancestor has no effect
Does anyone know what exactly I am doing wrong?
**EDIT: I've added a picture of the graph. The drawing is conceptual **
The problem was that I hadn't performed an hg pull before attempting the merge. Normally we do our development on a Windows machine using TortoiseHg. We modified the name of one of our resources on the support branch, from fooBAR to fooBar and ran into the mercurial case folding problem. We were trying to get around this by merging the branches on a Linux box. I am so used to using TortoiseHg that I forgot the most basic of commands!

hg convert from svn, need to pull branches from more than one place

I have a few odd issues with a svn repository I'm trying to convert to hg. Our repository looks more or less like this.
proj_root ___ trunk
\ \___ tags
\_____ branches __A
\ \__B
\_____Q __ C
\___ D
Ideally I could specify --config convert.svn.branches=branches;branches/Q or somesuch nonesense. (Q does not contain a branch in itself, just the two "sub branches".
I just finished converting a repository in which Q only had one subdirectory, and the solution there was easy. rename C/ . in a --filemap option, but that fails rather dramatically for this case (the Q branch interleaves C and D).
Ideally, I could simply ignore Q entirely in one pass, and then do a second conversion with the convert.svn.branches option set to branches/Q, but I cannot get the following syntax in the filemap to work:
exclude "Q C D"
nor
exclude "C D"
My hope was that excluding C and D would prevent any files from being imported on that branch, and since I have a specified filemap, the resulting empty commits would be removed. I can't get the exclude directive to exclude any directories, no matter the various syntax options I've tried.
Edit: The end result I'd like to have is a mercurial repo with trunk as the normal tip, and named branches A, B, C and D... that silly Q thing can just go away during the conversion, if I can figure out how.
For some reason when I tried this yesterday, it wasn't working, but today it works...
a filemap of
exclude "C"
exclude "D"
seems to be working properly now... I'm having an odd issue with the first conversion I'm doing crashing, but that's an issue to take up with the devs (unrelated)

How do I cherry-pick a single revision in Mercurial?

In Mercurial/TortoiseHg, given the following example, what is the easiest way to merge revision "G" into repo A without taking D,E and F (Assume that G has no dependency on D,E or F).
Repo A: A - B - C
Repo B (Clone of A) A - B - C - D - E - F - G
Is a patch the best bet?
Tonfa is right. What you're describing isn't 'merging' (or 'pushing' or 'pulling'); it's 'cherry-picking'. A push or a pull moves all the changesets from one repo to another that aren't already in that repo. A 'merge' takes two 'heads' and merges them down to a new changeset that's the combination of both.
If you really need to move G over but can't possibly abide having D,E,F there you should 'hg export' G from repo A, and then 'hg import' it in repo A. The Transplant extension is a wrapper around export/import with some niceties to help avoid moving the same changeset over multiple times.
However, the drawback to using import/export, transplant, and cherry-picking in general is that you can't really move over G without its ancestors, because in Mercurial a changeset's name is its 'hashid' which includes the hashids of its parents. Different parents (G's new parent would be C and not F) means a different hashid, so it's not G anymore -- it's the work of G but a new changeset by name.
Moving over G as something new, let's call it G' (Gee prime), isn't a big deal for some uses, but for others it's a big pita. When soon repo B get's a new changeset, H, and you want to move it over its parent will be changing from G to G', which have different hashes. That means H will move over as H' -- 100 changesets down the line and you'll have different hashids for everything all because you couldn't stand having D,E,F in repo A.
Things will get even more out of whack if/when you want to move stuff from Repo A into Repo B (the opposite direction of your earlier move). If you try to do a simple 'hg push' from A to B you'll get G' (and H' and by subsequent descendants) which will be duplicates of the changesets you already have in Repo B.
What then, are your options?
Don't care. Your data is still there you just end up with the same changesets with different names and more work on future exchanges between the two repos. It's not wrong, it's just a little clumsy maybe, and some folks don't care.
Move all of D,E, and F over to Repo A. You can move all the changesets over if they're harmless and avoid all the hassle. If they're not so harmless you can move them over and then do a 'hg backout' to undo the effects of D,E and F in a new changeset H.
Give G better parentage to begin with. It's mean for me to mention this because it's too late to go this route (without editing history). What you should have done before working on changeset G was to hg update C. If G doesn't rely on or require changesets D,E, and F then it shouldn't be their kid.
If instead you update to C first you'll have a graph like this:
A - B - C - D - E - F
\
G
then, the whole answer to this question would just be hg push -r G ../repoA and G would move over cleanly, keeping its same hashid, and D, E, and F wouldn't go with it.
UPDATE:
As pointed out in the comments. With modern Mercurials the hg graft command is the perfect way to do this.
Refering to the title, which addresses cherry picking in general, I give the example of working in one repo, as internet search engines might bring people here for cherry picking in general. Working in one repository, it would be done with hg graft:
hg update C
hg graft G
The result is:
G'
/
A - B - C - D - E - F - G
Extra warning: The two changesets will be treated as independent, parallel commits on the same files and might make you run into merge conflicts, which is why cherry picking should be avoided in general for branch management. For example, if G is a bug fix applied to a stable version branch bookmarked as 1.0.1, you should rather merge the freeze branch with it, and from time to time merge the master branch with the freeze branch's bugfixes.
Here's another approach:
hg import =(hg diff -c 7b44cc577701f956f12b029ad54d32fdce0a002d services/webpack/package.json)
This creates a diff for the changeset you want to patch in, then saves it to a temporary file and imports it. The filename(s) are optional.
<(...) also seems to work if you're not using zsh (creates a named pipe instead). Or you can manually save the patch to a file:
hg diff -c xxx > mypatchfile