Are most modern developers struggling to write code without this? If so, there is a fundamental problem that has nothing to do with levels of undo.
Are most modern developers struggling to write code without this? If so, there is a fundamental problem that has nothing to do with levels of undo.
Sometimes it's easiest to hit Cmd+Z a few times to check out how something looked at an earlier stage of a change. And then it's easy to Redo everything back to the current state. Rewinding changes back can even jog your memory as to why you did something. It's fast, simple, and effective. What's so bad about that?
The closest imaginable thing I might do is wrapping some block of code in an if(false) {..} or #ifdef it out, when I'm refactoring and feeling unsure about my changes. But is that even the same thing that we're talking about here?
Can't imagine how anyone doesn't do this - unless there's just a race of God-programmers I've never encountered that write everything perfect the first go. But I don't think so. :-)
All versions controls have a way to compare, merge and revert historical changes in and out of the current working copy.
I do all of these. I’d use undo/redo when I want to look at something I /just/ did, meaning while in the process of writing something. The git gutter when I stumble upon some change I want to see what was there before. Or Sourcetree for a full diff.
But also, `git diff`.
On one hand it's nice that there are tools to support devs who get lost in their undo-redo history, on the other I feel like it's a matter of good habits to not even have this problem.
of course changing habits is hard, so maybe tooling is justified in this case. I'm just happy I don't have nother "history" type mental model to deal with.
Git stash can be helpful. Stash your "wrong direction" change, then apply just the good chunks from your stash.
Yes, git diffs help, but once I’ve passed a parameterized suite of unit tests, never needed to undo/redo. Maybe not perfect the first go, but only need one/two tries to working code. Then refactor for readability.
Consider, for example, a bug recently introduced during a refactor at my work:
The programmer optimized a conditional based on a regex by transforming it into a simple string compare. All the tests passed, code/branch coverage was good. Except that he missed that the regular expression tested case-insensitively, and our test suite didn't test upper and lower case scenarios.
This simple mistake outlines a few flaws:
- coverage was not robust, because it didn't take into consideration the branches inside the regex (which one could interpret as a form of macro expansion)
- the limited number of inputs used to test failed to capture the broader domain of possible input
- the test did not reflect a successful refactor
Obviously this is a fairly complicated example despite a pretty simple change, and several pieces had to fail in order for this change to fail. But it affirms that even basic changes to code aren't necessarily adequately covered by TDD.
Yes, the developer who forgot to test different letter cases made a mistake. Yes, regular expressions bring their own problems. But fundamentally, the result was that passing the tests did not affirm fitness of the change. Rather, it only proved a limited subset of conditions were error-free.
Effectively, tests are loaded with false negatives, so trusting them to identify problems should be done with a massive grain of salt.
If the developer had simply copy/pasted the code he changed and compared the two, then it's exceedingly more likely that he would have noticed that his code didn't capture the full breadth of conditions in the previous code.
A bug existed in the test suite, to start, and then a bug was introduced into the codebase. A human being looking at the two lines of code as it was rewritten probably would have noticed the regression. But even a code review missed it because it was a fundamentally small change among the other, more "make sure this looks good" code.
Personally, I very much value copy/paste/compare changes and never treat the test suite for anything other than "well we haven't broken anything in any exceedingly obvious ways." Maybe you're a superhuman programmer, but I'd lean more towards "you've probably added more bugs than you realize".
The caps vs. no caps issue would be easily caught using randomString() as the test case.
This is from an example I did just yesterday.
Let’s say you’re moving a piece of code by cut n paste. You cut it but in the middle of changing you copied something else, maybe accidentally. Undo and cut it again. Redo and it’s now back in your clipboard.
You could copy from the diff but you’d get extra tokens to clean up.
I think you simply don't understand the workflow... when and why people do this.
Generally, the idea of referring to an older version of code while working on a later version is good and useful, is it not?
This is just one way of doing this.
make change => see result => cmd-z 1 time to fix result OR commit and keep coding
oops, it wasn't really fixed. cmd-z 3 times and see if that works
I know it's wrong, but what's right?
Nah, it's not wrong. You're testing your code changes live.
(I know you're joking)
If I'm reading this correctly it means applying a large number of undos to get to a previous editor state, followed by an equally large number of redos to then get back to where you started.
I can't recall every doing something like this.
The only time I seem to use undo is when I genuinely make some sort of editing mistake.
One reason I know I don't subconsciously do this is because I never struggle to execute an undo action.
However, on the rare occasions I need to do a redo I tend to struggle with the short cut key and usually go to the menu instead.
That tells me I use undo much more than redo.