Skip to content

Commit 4eb2708

Browse files
authored
README: add git rebase example (#28)
1 parent ce1c953 commit 4eb2708

File tree

1 file changed

+96
-4
lines changed

1 file changed

+96
-4
lines changed

README.md

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Baes
22

3-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/baes`. To experiment with that code, run `bin/console` for an interactive prompt.
3+
Welcome to your new gem! In this directory, you'll find the files you need to
4+
be able to package up your Ruby library into a gem. Put your Ruby code in the
5+
file `lib/baes`. To experiment with that code, run `bin/console` for an
6+
interactive prompt.
47

58
TODO: Delete this and the text above, and describe your gem
69

@@ -24,15 +27,102 @@ Or install it yourself as:
2427

2528
TODO: Write usage instructions here
2629

30+
### Anatomy of a Rebase
31+
32+
Let’s imagine we have the following chain of branches:
33+
34+
```
35+
main
36+
branch_01 # based on main
37+
branch_02 # based on branch_01
38+
branch_03 # based on branch_02
39+
```
40+
41+
We can say the top commit on `main` has hash `m1`. `branch_01` will have `a1`,
42+
`branch_02` will have `a1,b1`, and `branch_03` has `a1,b1,c1`.
43+
44+
Now let’s say we rebase merge `branch_01` onto `main`. If we rebase or squash
45+
commits onto another branch, it actually generates a _new_ commit hash, even if
46+
the code changes are the same. So `main` will have hashes `m1,a2`, where `a2`
47+
is a new hash for the same changes as `a1`. In this scenario, `branch_02` will
48+
still have commits `a1,b1` even though `main` has an equivalent commit `a2`. So
49+
what do we do? We rebase!
50+
51+
```
52+
git rebase main branch_02
53+
```
54+
55+
There are a series of possible outcomes.
56+
57+
1. It tosses commit `a1` because it has no changes from what is on `main`. Here
58+
we are left with a new `b2` commit hash on `branch_02`.
59+
2. Maybe you made some slight changes to `branch_01` based on feedback. When
60+
you rebase you end up with a conflict! Well, in this case the conflict is
61+
easy to resolve if it’s on `a1`. You simply skip it since you only care
62+
about commit `b1`: `git rebase --skip`. Then you again end up with `b2`, or
63+
maybe you have a conflict there as well, which you will need to resolve
64+
manually and use `git rebase --continue`.
65+
3. Maybe you made some major changes to `branch_01` based on feedback. Because
66+
of this there is no overlap between the new `a2` on `main` and the `a1` on
67+
`branch_02`. When you rebase `branch_02` on `main`, it cleanly applies the
68+
changes, leaving you with `a3,b2` on `branch_02`. This is the least optimal
69+
scenario, since you probably want commit `a3` to go away. You’ll need to do
70+
do an interactive rebase `git rebase -i main branch_02` and manually delete
71+
that commit. Thankfully, this doesn’t seem to happen all that often.
72+
73+
`baes` helps you easily address the first two cases. It rebases _all_ of your
74+
branches on the base branch (`main` by default). If it hits a conflict in the
75+
process, it will prompt you to skip this step in the rebase. If we are
76+
confident we only have one commit on our branch that we care about, we can skip
77+
up to the top commit:
78+
79+
```
80+
$ baes
81+
conflict rebasing branch branch_01 on main
82+
skip commit 1 of 2? (y/n) y
83+
conflict rebasing branch branch_01 on main
84+
skip commit 2 of 2? (y/n) n
85+
```
86+
87+
Then we fix the code and run `git rebase --continue`. This enables you to have
88+
long chains of branches without nearly as much of the tedium of handling rebase
89+
conflicts. If that’s still not fast enough for you and you’re feeling daring,
90+
you can run with the `--auto-skip` flag, which will automatically skip and only
91+
stop on the top commit. This has the caveats that 1) you should be sure you
92+
only have one commit on each branch and 2) you don’t have any one-off branches
93+
with a bunch of commits that might conflict, as it’ll skip those. The upshot is
94+
that on a branch like that you’ll probably end up with conflicts on the last
95+
commit as well, so you’ll be able to abort the rebase process (`git rebase
96+
--abort`) and restart it from scratch to handle the conflicts manually.
97+
98+
Once all your branches are rebased, you can clean up any that are up to date
99+
with `main`:
100+
101+
```
102+
git checkout main && git branch --merged | grep -v "\(main\|master\|staging\)" | xargs -r git br -d
103+
```
104+
105+
You can find a more aggressive git cleanup helper [here][gc].
106+
27107
## Development
28108

29-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
109+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
110+
`rake spec` to run the tests. You can also run `bin/console` for an interactive
111+
prompt that will allow you to experiment.
30112

31-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
113+
To install this gem onto your local machine, run `bundle exec rake install`. To
114+
release a new version, update the version number in `version.rb`, and then run
115+
`bundle exec rake release`, which will create a git tag for the version, push
116+
git commits and the created tag, and push the `.gem` file to
117+
[rubygems.org](https://rubygems.org).
32118

33119
## Contributing
34120

35-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/baes. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/baes/blob/main/CODE_OF_CONDUCT.md).
121+
Bug reports and pull requests are welcome on GitHub at
122+
https://github.com/[USERNAME]/baes. This project is intended to be a safe,
123+
welcoming space for collaboration, and contributors are expected to adhere to
124+
the [code of
125+
conduct](https://github.com/[USERNAME]/baes/blob/main/CODE_OF_CONDUCT.md).
36126

37127
## License
38128

@@ -41,3 +131,5 @@ The gem is available as open source under the terms of the [MIT License](https:/
41131
## Code of Conduct
42132

43133
Everyone interacting in the Baes project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/baes/blob/main/CODE_OF_CONDUCT.md).
134+
135+
[gc]: https://github.com/mockdeep/dotfiles/blob/414c34b6a35dd512c88fa86d4d1f896f603a5af2/bash/aliases#L123-L129

0 commit comments

Comments
 (0)