Exec
Overview
During an interactive rebase, you may want to ensure that each commit is not breaking the stability of your code.
For example, a typical use case would be to compile the code and run your automated tests: unit tests, integration tests, or any other validation tests.
Setup playground
From the course repository root, just call the creation script for this activity:
./scripts/create-playground.sh rebase-int_execThen go the the new playground directory and check the commit log.
cd playgrounds/rebase-int_exec ; git log --oneline25963ee (HEAD -> main) fix bug
4e8a251 add debug to enqueue/dequeue
2076350 implement size
5740296 implement dequeue
ee613c4 implement enqueue
ef879b4 add constructor and inner collection
686fdae class skeleton
8ac9f65 add test for queue size
b6d5e10 add test for dequeue on empty queue
d740741 add more tests for `dequeue()`
452f3d8 api use example for `dequeue()`
c74db95 api use example for `enqueue()`
2b2ac6b create file with draft specificationsActivity goal
In this activity, we will use the "exec" action in two different ways:
- Asking to run the command between each rebuilt commit;
- Punctual command execution inside the rebase action command script.
The first method just relies on using the --exec command-line argument when rebase is started. The "exec" command will then be added automatically between each commit in the rebase action script.
The second method is more aligned with other interactive rebase activities and relies on inserting a specific command execution inside the list of actions that will be performed during interactive rebase.
Run a command on each commit
In this first use case we want to execute a given shell command each time a commit is reapplied in the repository.
As I don't want you to have an specific setup, we have no build or tests to run. So we are just going to run two commands: display of date and a git log to follow progress.
Start the rebase on the last 3 commits:
git rebase --interactive --exec 'date && git log -1 --oneline' HEAD~3The rebase process will start and the "git-rebase-todo" file opens in your editor showing the following set of actions (comment lines are removed):
pick 2076350 # implement size
exec date && git log -1 --oneline
pick 4e8a251 # add debug to enqueue/dequeue
exec date && git log -1 --oneline
pick 25963ee # fix bug
exec date && git log -1 --onelineWARNING
As playground rebuild a new repository each time you create one, the SHA1 in this course are only example. Only consider those in your local repository as reference.
This is a very traditional rebase script, except that the requested command is inserted between each commit automatically.
Close the file and observe the result in the console.
Executing: date && git log -1 --oneline
Sun Nov 16 23:39:18 CET 2025
2076350 (HEAD) implement size
Executing: date && git log -1 --oneline
Sun Nov 16 23:39:18 CET 2025
4e8a251 (HEAD) add debug to enqueue/dequeue
Executing: date && git log -1 --oneline
Sun Nov 16 23:39:18 CET 2025
25963ee (HEAD, main) fix bug
Successfully rebased and updated refs/heads/main.You can see in the log above the outut of each command highlighted.
This is a very simple scenario that can be very helpful when you know that each commit produce a stable build.
But if you practice test-driven development, your log might contain compiling but failing tests, then commit of the code that make the tests pass.
In this case you need a more subtle approach.
Specific command in script
You already saw how to implement this in the example above. But we will now just run fewer and targetted commands.
Start a new rebase on the entire history:
git rebase --interactive --rootThis will open a "git-rebase-todo" file with entire log:
pick 2b2ac6b # create file with draft specifications
pick c74db95 # api use example for `enqueue()`
pick 452f3d8 # api use example for `dequeue()`
pick d740741 # add more tests for `dequeue()`
pick b6d5e10 # add test for dequeue on empty queue
pick 8ac9f65 # add test for queue size
pick 686fdae # class skeleton
pick ef879b4 # add constructor and inner collection
pick ee613c4 # implement enqueue
pick 5740296 # implement dequeue
pick 2076350 # implement size
pick 4e8a251 # add debug to enqueue/dequeue
pick 25963ee # fix bugLet's add few specific action in the middle of this rebase:
pick 2b2ac6b # create file with draft specifications
pick c74db95 # api use example for `enqueue()`
pick 452f3d8 # api use example for `dequeue()`
pick d740741 # add more tests for `dequeue()`
pick b6d5e10 # add test for dequeue on empty queue
pick 8ac9f65 # add test for queue size
exec echo 'pretend to compile tests and ensure it succeed' && git log --oneline -1
pick 686fdae # class skeleton
pick ef879b4 # add constructor and inner collection
pick ee613c4 # implement enqueue
pick 5740296 # implement dequeue
pick 2076350 # implement size
pick 4e8a251 # add debug to enqueue/dequeue
pick 25963ee # fix bug
exec echo 'pretend to compile and check unit tests are now passing' && git log --oneline -1The console will display something like:
Executing: echo 'pretend to compile test and ensure they succeed' && git log --oneline -1
pretend to compile tests and ensure it succeed
8ac9f65 (HEAD) add test for queue size
Executing: echo 'pretend to compile and check unit tests are now passing' && git log --oneline -1
pretend to compile and check unit tests are now passing
25963ee (HEAD, main) fix bug
Successfully rebased and updated refs/heads/main.Highlighted lines are the output of commands.
About execution folder
Note
Commands are execute at the repository root folder.
You can verify where command are executed by simply running the pwd shell command.
git rebase --interactive --exec 'pwd' HEAD~2Executing: pwd
/Users/sylvain/dev/lab/git-tutorials/playgrounds/rebase-int_exec
Executing: pwd
/Users/sylvain/dev/lab/git-tutorials/playgrounds/rebase-int_exec
Successfully rebased and updated refs/heads/main.What we learned
Interactive rebase can run commands at arbitrary stages of the rebase process.
This can be extremely useful when you need to ensure that your rebase is not introducing regressions or any breaking changes.