Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advice on how to add `squash` functionality to interactive rebase? #287

Open
Lia-C opened this issue Jun 3, 2015 · 2 comments
Open

Advice on how to add `squash` functionality to interactive rebase? #287

Lia-C opened this issue Jun 3, 2015 · 2 comments

Comments

@Lia-C
Copy link

@Lia-C Lia-C commented Jun 3, 2015

git rebase -i <base> can currently only pick commits. I'm planning on changing the pick button into some kind of mutually-exclusive slider (or set of radio buttons) so that you can either pick a commit or squash a commit.

Do you have any advice on which files I would need to edit to add squash functionality?
I was looking at src/js/git/commands.js and I suspect I'll need to change something in this section:

 rebase: {
    sc: /^gr($|\s)/,
    options: [
      '-i',
      '--solution-ordering',
      '--interactive-test',
      '--aboveAll',
      '-p',
      '--preserve-merges'
    ],
    regex: /^git +rebase($|\s)/,
    execute: function(engine, command) {
      var commandOptions = command.getOptionsMap();
      var generalArgs = command.getGeneralArgs();

      if (commandOptions['-i']) {
        var args = commandOptions['-i'].concat(generalArgs);
        command.twoArgsImpliedHead(args, ' -i');

        if (commandOptions['--interactive-test']) {
          engine.rebaseInteractiveTest(
            args[0],
            args[1], {
              interactiveTest: commandOptions['--interactive-test']
            }
          );
        } else {
          engine.rebaseInteractive(
            args[0],
            args[1], {
              aboveAll: !!commandOptions['--aboveAll'],
              initialCommitOrdering: commandOptions['--solution-ordering']
            }
          );
        }
        return;
      }

      command.twoArgsImpliedHead(generalArgs);
      engine.rebase(generalArgs[0], generalArgs[1], {
        preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges']
      });
    }
  },

I'll also need to edit the pop-up interactive rebase dialog so that instead of a pick button it has the mutually-exclusive slider/radio buttons.

@pcottle
Copy link
Owner

@pcottle pcottle commented Jun 5, 2015

Hey @Lia-C -- youll probably want to modify the src/js/git/index.js file which is a lot larger and holds a lot more of the internal logic. A few things youll have to watch out for:

-- What if they are trying to squash a commit with children? youll have to reattach the other children
-- What about branches / tags that point to those commits?
-- what about if that commit is a merge parent?

Since there were so many edge cases I didnt bother implementing it myself :P the UI changes shouldnt be horrible, but I would try to code up the core functionality first

@Lia-C
Copy link
Author

@Lia-C Lia-C commented Jun 20, 2015

I'm just going to use the same logic that git does for squashes. I suppose you didn't use actual git at all, and just rewrote the logic in js?

Could you provide a quick overview of what parts of the rebase "rebaseInteractive", "userSpecifiedRebase", and "rebaseFinish" take care of?

rebaseInteractive

The logic I'd add would be in src/js/git/index.js's GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation, options) method, correct?

userSpecifiedRebase

RebaseInteractive first does something with userSpecifiedRebase (see the code below). Where is the logic for assigning a value to userSpecifiedRebase?

var deferred = Q.defer();
  deferred.promise
  .then(function(userSpecifiedRebase) {
    // first, they might have dropped everything (annoying)
    if (!userSpecifiedRebase.length) {
      throw new CommandResult({
        msg: intl.str('git-result-nothing')
      });
    }
rebaseFInish

RebaseInteractive then does rebaseFInish:

this.rebaseFinish(userSpecifiedRebase, {}, targetSource, currentLocation);

Would I need to change some things in GitEngine.prototype.rebaseFinish = function( toRebaseRough, stopSet, targetSource, currentLocation, options )?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.