1

I would like to rebase my commit onto the latest in the develop branch. But, before everything is committed after the rebase, I want to review every file and check if it is correctly rebased or not.

For example,

Before:

develop  : commit a ----- commit b --- commit c
              \
Mybranch :     \ --commit my_a

After:

Develop  : commit a ----- commit b --- commit c
                                          \
Mybranch :                                 \ --commit my_a

But when simply type git rebase develop while I have Mybranch checked-out, git finishes rebasing by itself and automatically commits my_a to the top of commit c of develop.

So, currently I do this.

git rebase develop
git reset HEAD^
# every file in `my_a` goes to "not staged" state. I review everything.
git add (list_of_files_I_want_to_commit)
git commit

Is there any better way to do this with git commands?

Lani
  • 31
  • 3
  • 1
    Why don't you simply review the commit and undo it if it is "wrong"? Why undo the commit, review the changes, then recreate the commit? Why not review the commit and only undo/amend if required (which I assume will be in the minority of the cases?) – knittl Mar 17 '22 at 06:49
  • What does `git add ~~` do? I've never used that before. – Gabriel Staples Mar 17 '22 at 07:00
  • @knittl Actually I want to find a way to make git to treat every files in my_a commit as "conflicted" so I could double check and confirm. There were some cases that no conflicts happened but actually auto rebase did not work correctly. After experiencing that I thought it is better to review every files in my commit after rebase. – Lani Mar 17 '22 at 07:29
  • 1
    @Gabriel Sttaples I just typed ~~ instead of actual file names in my commit. Actually it should be like git add files_need_to_be_commited – Lani Mar 17 '22 at 07:31
  • Lani, regarding your comment to @knittl, I had similar struggles with wanting to check my rebased files and see what was dfiferent from before the rebase, and came up with my `git changes` command and workflow. Study [my answer](https://stackoverflow.com/a/71508399/4561887) to see what I'm talking about. Be sure to upvote any helpful answer, and mark the best one as correct if one solves your problem completely. That's the best way to say thank you if someone is able to help you out. – Gabriel Staples Mar 17 '22 at 07:36

2 Answers2

0

You can set the expected pull action for this branch

git config branch.never.rebase false

You can also make sure any new branch is rebased on pull

git config branch.autoSetupRebase never
Ravi Ranjan
  • 84
  • 1
  • 3
0

What you're trying to do, I think, is something I've struggled with a few years back too, and I've come to the following solution and conclusions and processes:

There is no sense in uncommitting my_a with git reset HEAD^ or git reset HEAD~ just so you can then git difftool it immediately to see what changes my_a is going to make.

Rather, just check those changes withOUT doing git reset HEAD~, like this:

# Run after the rebase
git diff HEAD~..HEAD

Even better, set meld as your difftool and do:

git difftool HEAD~..HEAD

Then, if you see anything wrong, fix it and make a new commit with commit message Fix errors from rebase:

# run after the rebase
git difftool HEAD~..HEAD

# If you see any errors, fix them, then commit everything and make a new commit
git add -A
git commit -m "Fix errors from rebase"

But, even better than that, in my opinion, is to see what changes were added upstream in develop that you do NOT have in my_a. You need to check these additions you did NOT do to ensure they do NOT conflict with your changes!

To do that, run this after the rebase:

git difftool my_a_BEFORE_THE_REBASE my_a

But, to do that you need to know the commit hash before you rebased, so, use this workflow instead in order to create a backup branch to compare against:

# before the rebase:

# ensure you are on your feature branch, my_a
git checkout my_a
# make a backup branch of branch my_a
git branch my_a_BAK
# Fetch latest develop withOUT having to check it out first
git fetch origin develop:develop
# rebase onto latest develop
git rebase develop
# manually fix any conflicts and then continue
git rebase --continue

# after the rebase:

# compare against your backup branch to look at upstream changes added into
# develop to ensure they do NOT conflict with your changes
git difftool my_a_BAK my_a
# If you see any errors, fix them, then commit everything and make a new commit
git add -A
git commit -m "Fix errors from rebase"

BUT, there's a big problem! What if develop is a HUGE repo used by hundreds of developers who just added HUNDREDS of new files!?

Now, git difftool my_a_BAK my_a will show you all of these hundreds of new files that have nothing to do with your changes!

Oh, wo is me! Wo is me! :)

The solution is to only check the files you touched by my_a. To do that, you need to run this:

# NOT this; it could show HUNDREDS of files!
git difftool my_a_BAK my_a

# do this instead
git difftool my_a_BAK my_a -- myfile1.c myfile2.c myfile3.c

...where myfile1.c myfile2.c myfile3.c are the only files you touched.

To see a list of all files you touched, run this (yes, with 3 dots):

git diff --name-only develop...my_a

Then, manually type those files into the command above in place of myfile1.c myfile2.c myfile3.c.

Well shoot! That's a pain! What if I have 40 files? I don't want to copy-paste all that garbage!

Final answer

That's why I wrote git-changes.sh. It solves all those issues above, and gets all those files for you.

Run it in your workflow like this:

# before the rebase:

# ensure you are on your feature branch, my_a
git checkout my_a
# make a backup branch of branch my_a
git branch my_a_BAK
# Fetch latest develop withOUT having to check it out first
git fetch origin develop:develop
# rebase onto latest develop
git rebase develop
# manually fix any conflicts, `git add` the files, and then continue with:
git rebase --continue

# after the rebase:

# Compare against your backup branch to look at upstream changes added into
# develop to ensure they do NOT conflict with your changes.
# The general format of `git changes` is 
# `git changes <common_base> <backup_branch>`. Run `git changes` with
# NO args to see the help menu.
git changes develop my_a_BAK   # <=== my script === 
# If you see any errors, fix them, then commit everything and make a new commit
git add -A
git commit -m "Fix errors from rebase"

To get git changes as a command, just rename git-changes.sh to git-changes and move it to any directory already in your PATH, such as to the ~/bin dir if using Ubuntu with a default ~/.profile file. Note: if you don't have a default ~/.profile file, get it from /etc/skel/.profile:

# copy the default .profile file to your home dir in Ubuntu
cp -i /etc/skel/.profile ~

Run git changes with no arguments to see its full help menu.

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
  • 1
    Thanks! The other way I found is, after rebase review everything by amending last commit but this works only when my commit on MyBranch is combined to one. Your script works in case there are multiple commits on MyBranch. – Lani Mar 18 '22 at 09:06
  • @Lani, I'm glad it helps you. Don't forget to upvote any helpful answers and mark one as correct if it answers your question. – Gabriel Staples Mar 18 '22 at 16:12