Is there a way of committing code transformations or refactorings in git, perhaps as metadata for an actual commit, so that code editing tools can apply the change as a conceptual transformation instead of a whole lot of text changes?

To illustrate, suppose that a class has a public property FOO. Someone might rename FOO to BAR and commit that. Unfortunately now every other branch that uses FOO will now have a merge conflict or break on compilation. If instead the change were somehow stored as "refactor: rename FOO to BAR" then, on rebase, the change would be implemented in other branches as well.

It might be that some language aware code tools are smart about this and say "Oops, this thing has no property FOO. Did it ever have a property FOO? Let me look back in git history and aha, yes it did, it is now called BAR. Let me update FOO to BAR here as well.". That would not need any special annotation.

Personally my answer is "don't rename stuff unless you absolutely have to". Unfortunately editors have refactor buttons and some people are trigger happy. If there is a button, why not press it? It is so quick and easy!

  • It doesn't support scala out of the box but there seems to be a windows plugin that might be adapted: github.com/sageserpent-open/SemanticMergeScalaPlugin – Max Murphy Jul 13 '18 at 11:51
  • 2
    I'd refer you to the second page of Per Cederqvist's Version Management with CVS: "CVS is not a substitute for management. ... CVS is not a substitute for developer communication." Your developers clearly don't understand the ramifications of their actions. Get some discipline into their lives. – Blrfl Jul 13 '18 at 11:54
  • How frequently do you do merges? If the code is fairly up to date between the branches renaming should go pretty smoothly. – DaveG Jul 13 '18 at 12:45
  • That depends on the individual programmer and on how confident that they are that a given branch can be rebased without conflict. More radical changes => greater likelihood of breaking changes. However that is kinda beside the point. If the rebase goes smoothly but renames a property, a normal rebase is not going to find all the new uses of that property and fix them. Ditto with libraries being moved, signatures changing and so on. One push can interrupt the workflow of the entire team. Multiple people actively following the same "refactor is cheap" mentality and you have havoc. – Max Murphy Jul 13 '18 at 13:10
  • 1
    Refactoring should be cheap. If your use of source control is keeping it from being cheap that doesn't mean you should stop refactoring. It means you should rethink the way you're using source control. Same with unit tests, integration tests and peer reviews. Refactoring is WHY we use code instead of soldering irons. Clamp down on refactoring and your code is dead. Code is like concrete. Stir it often or it will set and become hard. – candied_orange Jul 13 '18 at 14:28

In git, you could achieve this by using a custom merge driver. Unfortunately, a merge driver that used syntax trees would be fairly complex and also language-specific. I'm not personally aware of any existing implementations, but it's certainly achievable.

  • That is an idea. I have played with that before when getting clean merges of json documents. There the syntax is super simple though and there were no remote references to worry about. At least, I did not worry about them! References would be an issue e.g. in jsonschema that has definitions that could be renamed and all the references would have to be updated. That might be a good playground to start with. – Max Murphy Jul 13 '18 at 12:00

This isn't a source control problem. Since you haven't specified a language, I can make some generalizations.

Languages like Java and C# allow you to annotate code as being "obsolete." This should generate a compiler warning. Most languages that support these kinds of annotations allow you to show a message in the compiler output.

That is step #1.

Step #2 is communicating with your team.

Renaming things should be done when it makes sense, but it shouldn't be done in a vacuum. You have to communicate these things. The annotations that generate warnings when compiling the code do two things:

  1. Show other developers how to fix the warning
  2. Gives other developers time to finish their thoughts before dealing with the renamed identifier.

At some point you can either remove the "renamed" identifier, or pass a flag to the annotation that causes a compiler error, forcing people to fix it.

Source control is not the answer. This is all about communication and coordination.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.