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.