Mercurial shortcut to hsitedit all drafts - command-line

Whenever I need to use hg histedit, I do something like this:
Using TortoiseHG to determine the lowest level draft number
Hg histedit -r {lowest level draft number}
This process takes quite a bit of time for something that seems rather common. Is there a shortcut for this, something like, perhaps hg histedit -s draft?

You can use mercurial's revsets to accomplish that! To find the rev number of the first draft changeset:
hg log -r "first(draft() and ancestors(tip))"
I added the ancestors(tip) clause since my repo has draft changes on several branches at the moment :).
I believe there is a place in tortoise where you can search using revsets, but I don't use tortoisehg all that often.
Some commands can accept revsets as arguments for the --rev switch, but I don't believe it is universal.

Related

Does a bisect in version control benefit from using a rebaseif workflow?

The rebaseif mercurial extension automates the process, when pulling, of doing a rebase only if the merge can be done automatically with no conflicts.  (If there are conflicts to resolve manually, it does not rebase, leaving you ready to do a manual merge of the two branches.)  This simplifies and linearizes the history when developers are working in different parts of the code, although any rebase does throw away some information about the state of the world when a developer was doing work. I tend to agree with arguments like this and this that in the general case, rebasing is not a good idea, but I find the rebase-if philosophy appealing for the non-conflict case. I’m on the fence about it, even though I understand that there are still risks of logic errors when changes happen in different parts of the code (and the author of rebaseif extension has come to feel it’s a bad idea..)
I recently went through a complicated and painful bisect, and I think that having a large number of merges of short branches in our repository was the main reason the bisect did not live up to its implied O(lg n) promise.  I found myself needing to run "bisect --extend" many times, to stretch the range beyond the merge, going by a couple of changesets at a time, essentially making bisect O(n).  I also found it very complicated to keep track of how the bisect was going and to understand what information I'd gained so far, because I couldn't follow the branching when looking at graphs of the repository.
Are there better ways to use bisect (and to look at and understand the revision history) or am I right that the process would have been smoother if we had used rebaseif more in development. Alternately, can you help me understand more concretely what may go wrong using rebase in the non-conflict case: is it likely enough to cause problems that it should be avoided?
I’m tagging this more generally (not just mercurial) since I think rebaseif matches a more typical git workflow: git users may have seen the gotchas.
I think the answer is simple: you have to devide between hard bisects or risky rebasing.
Or, something in between: only rebase if it is very unlikely that the rebase silently breaks things. If a rebase involves only a few changesets which additionally are semantically distant to the changes they are rebased on, it's usually safe to rebase.
Here's an example, where a conflict-free merge breaks things:
Suppose two branches start from a file with this content:
def foo(a):
# do
# something
# with a (an integer)
...
foo(4)
In branch A, this is changed to:
def foo(a):
# now this function is 10 times faster, but only work with positive integers
assert a > 0
# do
# something with
# with a
...
foo(4)
In branch B, it is changed to:
def foo(a):
# do
# something
# with a (an integer)
...
foo(4)
...
foo(-1) # now we have a use case where we need to call foo with -1
Semantically, both edits conflict with each other. However, Mercurial happily merges them without conflicts (in both cases, when rebasing or when doing a regular merge):
def foo(a):
# now this function is 10 times faster, but only work with positive integers
assert a > 0
# do
# something with
# with a
...
foo(4)
...
foo(-1) # now we have a use case where we need to call foo with -1
The advantage of a merge is that a it allows to understand what went wrong at some later point, so you can fix things accordingly. A rebase might throw away information you need to understand bugs caused by automatic merges.
The main argument against git rebase seems to be a philosophical one around "losing history", but if I really cared about that I'd make the final build step a checkin (or the first build step to track all the failed builds too!).
I'm not particularly familiar with Mercurial or bisecting (except that it's a bit like git), but in my month-and-a-bit with git I exclusively stuck to rebase. I also use git rebase -i --autosquash and git add -p a lot.
IME, there's also not that much difference between a rebase and a merge when it comes to fixing conflicts — the answer you linked to suggests "rebaseif" is bad because the "if" conditions on whether the merge proceeded without conflict, whereas it should be conditioned on whether the codebase builds and tests pass.
Perhaps my thinking is skewed by an inherent weakness in git's design (it doesn't explicitly keep track of the history of a branch, i.e. the subset of commits that it's actually pointed to), or perhaps it's just how I work (check that the diff is sane and that it builds, although admittedly after a rebase I don't check that intermediate commits build).
(Aside: For personal projects I often would like to keep track of each build output and corresponding source snapshot, but I've yet to find anything which is good at doing so.)

In Eclipse, will this series of actions on my project in CVS do what I want them to do?

I am not terribly familiar with CVS, but at my work I have a project in CVS that is shaped like this:
------A-------B D Main branch
|
|----------C My branch
The project at tag A works. At tag B, it does not, so A is in production. This was all done years ago. I come along and want to make changes to A, but I don't know much about B, and since I don't want to touch it, I make a branch. At C, I have decided that my changes are important, and B is irrelevant. I want whatever is at C to sit at D on the main branch, and everything from A to B to be ignored.
Someone at my work suggested that I copy, via the OS, the contents of my branch over the contents of the main branch, but then said it breaks the history and I should ask Stack Overflow for a better solution first.
I'm doing this all in Eclipse, so my idea was to open A in the workspace, merge C into it, and commit the result to the head, prioritizing my side for each and every difference, to get D. However, I'm afraid that the merge from AC to D mightn't do what I expect, and I don't want to break things.
My question is: Will this do what I expect it to do? If not, what is a safer way to do this than my co-worker's suggestion?
I prefer to use WinCVS if I have to use CVS at all. Some of our legacy stuff uses CVS and it's a pain.
You merge back into the main branch exactly the same way as SVN, but it just looks a lot more complicated. See if WinCVS makes it easier and let me know. Don't do the copy & repost though, that's a really bad approach.
http://www.eclipse.org/articles/article.php?file=Article-BranchingWithEclipseAndCVS/article2.html briefly shows the CVS Merge function. You'll want to find the tag that represents the point where you diverged from HEAD to make use of this.
Turns out, no, it won't do what I expect. Merging C to A works as expected, but committing AC over B does not, as I am working under the A tag, not the HEAD tag (B), and committing only changes the older tag.
Instead of the proposed method, it should be done in the opposite order, or all at once. The HEAD should be reverted to A, and then the branch can be merged, or you can do them at the same time. CVS in Eclipse doesn't have an easy way to do this cleanly, but it does have an annoying way to do it cleanly:
Open the HEAD in your workspace.
Right-Click the project -> Compare With -> Another Branch or Version...
Choose the point where the branch splits (A) or the end of the branch you want to replace the HEAD with (C).
The Synchronise view will show you every file that is different between the two versions.
For every file that is different, go back to the Package Explorer view and Right-Click -> History... (Not "Another Branch or Version..." because then you'll be working with multiple tags at once, and commits will go to different places). Then choose the tag that contains the version of the file you want to keep (A or C, depending on what you're comparing with).
Once there are no remaining differences, commit.
If you compared with C, both branches are in the same state. You're done. D will have what you want.
Instead, if you compared with A, you can now merge C onto the HEAD. Once you commit again, D will have what you want.

Is there some commit reminder for Subversion/etc for Eclipse?

Something that will alert your/force you to commit after editing X number of files, or modifying X number of lines of code, or writing X number of lines of code.
Edit:
There's clearly no feasible way for an automated system to determine if some realizable code chunk is complete but this would be good enough for me. I don't want to use this as an "autosave" feature but more as a brain jog to remember to commit once at a suitable point.
I completely agree with the other anwsers, but I think one can use this approach if, say, you want to ensure that you make small commits rather than large ones, especially in DVCS's like Git
I think you can setup a Scheduled Task or Cron, which will hit your working directory and run something like:
svn diff | grep -E "^\+ " | wc -l
and if the count is greater than something that you deem is when you want to commit, you can make it give you a reminder. I don't think you can integrate such a thing in Eclipse.
That's not what commits are for. They are not some sort of backup mechanism. You do a commit when a piece of work has reached some state that you want to remember, normally because you are happy with it. It makes no sense at all to do them every X hours or every N lines of code.
Usually it's just a workflow thing and a habit you should get into.
Commits should be related to the work you are doing - so that reverting is meaningful. It's pretty hard for anything else to detect that except you.

Is there a diff tool (patch) that is aware of indentation?

I'm regularly using the gnu-utils patch and diff. Using git, I often do:
git diff
Often simple changes create a large patch because the only that changed was, for example, adding a if/else loop and everything inside is indented to the right.
Reviewing such a patch can be cumbersome because only line by line manual comparison can indicate if anything has essentially changed within the indented code. We may be speaking about a few lines of code only, or about dozens (or much more) of nested code. (I know: such an hypothetically large function would better be split into smaller functions, but that's beside the point).
Can't GNU diff/patch be aware when the only change within a code block is the indentation and let the developer know as much?
Are there any other diff tools that operate this way?
Edit: Ok, there is --ignore-space-change but then we are in a either/or situation: either we have a human-more-readable patch or we have a complete patch that the machine would know how to read. Can't we have the best of both world with a more elaborate diff tool that would show to the human space changes for what they are while allowing the machine to apply the patch fully?
With GNU diff you can pass -b or --ignore-space-change to ignore changes in the amount of white space in a patch.
If you use emacs and have been sent a patch, you can also use M-x diff-ignore-whitespace-hunk to reformat the patch to ignore white space in a particular hunk. Or diff-refine-hunk to highlight changes at a character by character level, which tends to point out the "meat" of a change.
As for applying patches, you can use the -l or --ignore-whitespace with GNU patch to ignore tabs and spaces changes. Just be careful with Python code :-)
For what is worth, using git difftool with a tool like meld or xxdiff makes the diff much more readable.
I don't know about git diff. But a diff-like tool that understands not just indentation but in fact any layout changes in your target language is our Smart Differencer.
This tool parses the before- and after- versions of your code the same way compiler does, and compares the resulting syntax trees, so it isn't affected by whitespace changes (except semantically important whitespace such as Python indentation) of any kind, inserted or deleted comments, or even change of radix on constants.
The result is report in terms of programmer editing actions ("move, insert, delete, copy, rename") over language structures (expressions, statements, declarations, blocks, methods, ...) rather than "insert line" or "delete line".
I try to not do file-wide indentation changes in the same commit as some other changes. And I commit the indentation changes in a separate commit before or after, with a commit message of "Changed indentation only.", to make it clear so that no manual diff inspection is needed, to see if something else was changed.

Whitespace in version control (darcs)

A junior programmer in our office has an unfortunate (but understandable) habit of using Eclipse's "Correct all the indentation in this file" feature. As a result, his checked out copy includes thousands of lines that register as changes, simply because the whitespace is different. Accepting all these changes - while other people are also working on the same code, some of them in different offices - will lead to conflicts. At the same time we don't want to throw away all the work he's done.
Are there any options for Darcs to ignore or normalise whitespace changes; or tools that can revert the differences?
i have never used darcs, but this is how i'd deal with it:
(cd newbies-copy && darcs diff --diff-opts -w) | (cd fresh-copy && darcs apply)
hopefully i got the darcs commands right, just skimmed the manual.