Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Fixup and autosquash
1. - My name Shawn Sorichetti
- going to talk about handling
coding mistakes with git
FIXUP
AND
AUTOSQUASH
Shawn Sorichetti
shawn@sorichetti.org
https://ssoriche.com
2. - I like to start git repositories with an
empty commit, as it creates a rebase
point at the beginning of the repository
- because yes, you can make a mistake
in the initial commit
- creating a develop branch to follow
process
- and now a feature branch
A LITTLE ENVIRONMENT SETUP
git init .
git commit -m "Initial commit" --allow-empty
git checkout -b develop
git checkout -b getting_started
Fixup and Autosquash // Shawn Sorichetti
3. - some super simple code just
to get the commits going
- this is far from real world, but
needed something to show
- Is that a good commit
message? No.
CREATE SOME SIMPLE CODE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
print "nHi namen";
git add my_name.pl
git commit -m "Initial code commit"
Fixup and Autosquash // Shawn Sorichetti
4. - some super simple code just
to get the commits going
- this is far from real world, but
needed something to show
- Is that a good commit
message? No.
CREATE SOME SIMPLE CODE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
print "nHi namen";
git add my_name.pl
git commit -m "Initial code commit"
Fixup and Autosquash // Shawn Sorichetti
5. - Going to introduce a change
to the code
CREATE A CHANGE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
chomp($name);
print "nHi namen";
git add -u
git commit -m "Add newline removal"
Fixup and Autosquash // Shawn Sorichetti
6. - this changes the way the
code works, and deserves a
separate change
CREATE A CHANGE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
chomp($name);
print "nHi namen";
git add -u
git commit -m "Add newline removal"
Fixup and Autosquash // Shawn Sorichetti
7. - when I created the initial code
I made a mistake, did you catch
it?
- failed to identify name as a
variable so name is printed
rather than the $name contents
INITIAL MISTAKE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
chomp($name);
print "nHi namen";
Fixup and Autosquash // Shawn Sorichetti
8. INITIAL MISTAKE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
chomp($name);
print "nHi $namen";
Fixup and Autosquash // Shawn Sorichetti
9. INITIAL MISTAKE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
chomp($name);
print "nHi $namen";
git add -u
Fixup and Autosquash // Shawn Sorichetti
10. - As this was a mistake and
doesn't change the story, it
should not be a separate commit
- just fix the existing commit
- the change has been staged
- but how do we deal with this
mistake
THEN WHAT DO YOU DO?
Fixup and Autosquash // Shawn Sorichetti
11. - create a new commit with a
distinctive subject reminding
me of what I need to do
- yeah... I forgot.
WHAT I USED TO DO
git commit -m "XXX Rebase and fix up into Initial commit"
Fixup and Autosquash // Shawn Sorichetti
12. AND THEN THIS HAPPENS
git checkout develop
git merge getting_started
git push origin develop
git log origin/develop --oneline
02cde46 (HEAD -> develop) XXX Rebase and fix up into Initial commit
46c49cf Add newline removal
9a0cb79 Initial code commit
cf186bb (master, develop) Initial commit
Fixup and Autosquash // Shawn Sorichetti
13. AND THEN THIS HAPPENS
git checkout develop
git merge getting_started
git push origin develop
git log origin/develop --oneline
02cde46 (HEAD -> develop) XXX Rebase and fix up into Initial commit
46c49cf Add newline removal
9a0cb79 Initial code commit
cf186bb (master, develop) Initial commit
Fixup and Autosquash // Shawn Sorichetti
15. - creates a special kind of commit
that includes the subject of the
commit to be fixed
- now this isn't really what I
normally do, I use git log to
find the commit and capture the
SHA and just use that
WHAT I SHOULD HAVE DONE
git commit --fixup :/Initial
Fixup and Autosquash // Shawn Sorichetti
16. - which is a regex
- this for instance results in the latest commit with the
message matching Initial
- This power by the way is brought to you by rev-parse
- the --fixup argument accepts anything that git rev-
parse will allow
- highly recommend having a read through there
- it's amazing what all can be done to specify a
commit
- one of which is the latest commit of the file, but
that's another talk...
WHAT I SHOULD HAVE DONE
git commit --fixup :/Initial
git help rev-parse
Fixup and Autosquash // Shawn Sorichetti
17. NOW MY COMMITS LOOK LIKE THIS
git log --oneline
009b808 (HEAD -> getting_started) fixup! Initial code commit
46c49cf Add newline removal
9a0cb79 Initial code commit
cf186bb (master, develop) Initial commit
Fixup and Autosquash // Shawn Sorichetti
18. - wait a minute, before you had
XXX now you have fixup!
- this doesn't look better
HOW IS THAT BETTER?
Fixup and Autosquash // Shawn Sorichetti
20. - notice that git rebase moved the fixup
commit into
location and applies the fixup option
automatically
- now this is a simple example where there's
only 3 commits
- but imagine 20 - 40 commits, and trying to
move them around
- by hand
AUTOSQUASH
git rebase -i develop --autosquash
pick 9a0cb79 Initial code commit
fixup 2e72bb0 fixup! Initial code commit
pick 46c49cf Add newline removal
# Rebase cf186bb..2e72bb0 onto cf186bb (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
Fixup and Autosquash // Shawn Sorichetti
21. - Because this code is so
small, it does generate a
merge conflict
- which is pretty easy to fix
- just mentioning it for
completeness
MERGE CONFLICT
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
<<<<<<< HEAD
print "nHi namen";
=======
chomp($name);
print "nHi $namen";
>>>>>>> 2e72bb0... fixup! Initial code commit
Fixup and Autosquash // Shawn Sorichetti
22. GREAT FOR CODE REVIEWS
Fixup and Autosquash // Shawn Sorichetti
23. - this is a valid concern
FEEDBACK PROVIDED
Fixup and Autosquash // Shawn Sorichetti
24. - This is a simple fix
- if condition not to print if
there is no value
- yes, this doesn't handle if a
persons name is 0 or false
FIX IT IN THE CODE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
chomp($name);
print "nHi $namen" if $name;
git add -u
git commit --fixup :/Initial
git push origin getting_started
Fixup and Autosquash // Shawn Sorichetti
25. - stage the change for commit
- commit the change again
back to the initial commit
- the history of the request is
kept in the merge request, a
separate commit isn't required
FIX IT IN THE CODE
#!/usr/bin/env perl
use strict;
use warnings;
print "Enter your name: ";
my $name = <STDIN>;
chomp($name);
print "nHi $namen" if $name;
git add -u
git commit --fixup :/Initial
git push origin getting_started
Fixup and Autosquash // Shawn Sorichetti
26. - this was the merge request
state before the change was
push
THE MERGE REQUEST
Fixup and Autosquash // Shawn Sorichetti
27. - GitLab has automatically
marked the merge request as
Work in Progress
- it will not allow this merge
request to be completed until
this state is resolved.
THE MERGE REQUEST NOW
Fixup and Autosquash // Shawn Sorichetti
28. - GitLab has added the fact
that this code has changed
directly to the discussion
- this allows the original
reviewer to mark the
discussion as resolved
AND WHAT DOES THE FEEDBACK LOOK LIKE?
Fixup and Autosquash // Shawn Sorichetti
29. - once the approval is obtained, we
rebase the branch again, to squash the
fixup
- and we force push the branch to get
the clean history
- at this point the Merge Request Work
in Progress status needs to be
resolved
APPROVED
git rebase -i develop --autosquash
git push --force-with-lease origin getting_started
Fixup and Autosquash // Shawn Sorichetti