Home > Back-end >  Git command to prevent rebase from completing without letting me check the changes first
Git command to prevent rebase from completing without letting me check the changes first

Time:03-17

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?

CodePudding user response:

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

CodePudding user response:

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
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.

  • Related