Even seasoned developers get in trouble with Git, and fixing a botched branch/PR seems to require a deep understanding of Git's numerous concepts—a lot of theory just to get things done. This talk (originally presented at RubyConf Brazil 2016, then at Shopify) re-introduces Git (and GitHub) from the point of view of a pull request, going through tricky spots that show up time and time again, focusing on what we should know in order to avoid those problems—or at least to control the damage.
10. Hovertext:“If that doesn't fix it, git.txt
contains the phone number of a friend
of mine who understands git.
Just wait through a few minutes of 'It's
really pretty simple, just think of
branches as...' and eventually you'll learn
the commands that will fix everything.”
Git - 30/Out/2015
https://xkcd.com/1597/
11. Neither rookie nor expert
Good professionals will try to become
proficient in their tools - not become
specialists in all of them
12. Expert Advice
● “Do a git pull once in a while”
● “Never use git pull”
● “Always rebase!”
● “Never rebase!!!”
● ...
18. Git
A system that allows people to work
with source code in an orderly and
simultaneous fashion
19. Commit
When a meaningful change is made,
you take it to the stage in order to
take a snapshot (commit)
A92347C2…1F2493E34: Increase submit button size
DescriptionID
20. Commit == snapshot
“Git is all about composing and saving
snapshots of your project and then
working with and comparing those
snapshots”
http://gitref.org/basic/
21. Branch
Successive commits form a timeline
One can commit into alternative
timelines (branches) and later integrate
those with the main timeline (master)
22. Group work
Your commits “live” in your local
repository (.git/)
You can push commits to other
people’s repositories (remotes), and
also pull commits from there
23. Organizing your group
This flow of commits/branches can be
organized in several ways (workflows)
A central repository that
enables code reviews by means
of pull requests helps a lot...
24. ● Refresh master (remote ⇒ local)
● Create new branch from there
● Commits, commits, commits!
● Push, PR (my branch ⇒ master)
●
●
25. But what if...
● ...CI* fails?
● ...other devs suggest changes?
● ...master changed while I worked?
*Continuous Integration
29. It can get really bad
● Irreconcilable conflicts
● Alien commits on my PR
● Commit is there, code is not
● The @#%@ button is still grey
● ...
30. How can we fix/avoid that?
By understanding what is happening on
a pull request to identify (and avoid)
traps, or, as a last resource, to rebuild
our PR with minimal effort
33. git merge
Includes commits from another branch in
the current one, without changing them
(an extra commit at the end will
consolidate changes from both sides)
34. How can that go wrong?
Consolidating changes from two
different timelines becomes more
complex as they diverge
36. If you can’t avoid it
There are several ways to make a
branch compatible with master again
Our workflow works well with rebase
37. git rebase
Rebuild the branch from its original
point (by default), creating new commits
identical to the original ones (by default)
(hint: these defaults won’t help you)
38. What can I do with rebase?
● (re-)base your changes on a more
recent master
(e.g.: git fetch; git rebase origin/master)
● Simplify your commits
(e.g.: git rebase --interactive master)
39. How can that go wrong?
Updating the branch and simplifying
commits at the same time is tricky
Rewriting a branch that is already
published causes incompatibilities
40. PR prep suggestion (1)
Recreate your branch from a
more recent master
(without changing the commits)
git checkout master
git pull
git checkout my-branch
git rebase master
41. PR prep suggestion (2)
Simplify your commits
(without changing the branch point)
git rebase –-interactive master
42. Suggestion ≠ rule
If the master didn’t change (much),
don’t botter updating
If your commits are clear,
don’t bother interacting
43. After the PR is created
New commits can be added to the
remote, just git push them
Rebase, however, isn’t that simple
(why?)
47. Avoiding further trouble
Just like before the first push, don’t
change the start point and
simplify commits at the same time
A new commit is always less
tricky than a rebase
50. git cherry-pick
Reproduces in your branch the
changes from a single commit
(even a branch-less one)
git cherry-pick id
51. Cherry-pick good commits
Instead of recreating changes manually,
we can cherry-pick the original
commits into a fresh branch
But we need to find those commits...
52. git log x git reflog
git log lists commits created in the
current branch (lots of search options)
git reflog lists any operations that
affected the local repository in any way
53. git reflog
f84195a HEAD@{0}: checkout: moving from 1468-more-resilience-on-in
d5a8868 HEAD@{1}: commit: Log the invalid listing on offer-less of
79e7c98 HEAD@{2}: commit: Better test naming and more detailed log
31e2ac1 HEAD@{3}: checkout: moving from master to 1468-more-resili
f84195a HEAD@{4}: rebase finished: returning to refs/heads/master
f84195a HEAD@{5}: pull --rebase --autostash: checkout f84195a626e9
ac12705 HEAD@{6}: rebase finished: returning to refs/heads/master
ac12705 HEAD@{7}: pull --rebase --autostash: checkout ac127053051c
...
54. #howto
1. Find all the commits that were
supposed to be on your PR
git log • git reflog •
55. #howto
2. Sync your master with the server
and create a brand new branch from it
git checkout master
git pull
git checkout -b new-branch
57. #howto
4. Replace the old branch with the new
one (on local and remote repos)
git checkout master
git branch -D my-branch
git branch -m new-branch my-branch
git checkout my-branch
git push –-set-upstream origin my-branch
--force
59. Conclusion (1)
You don’t need to know everything
about git, but it’s a good idea to have a
solid understanding of some concepts
(e.g.: commit, branch, merge, rebase)
62. Don’t use the --force, Luke
Make a habit of trying “vanilla” git
push before adding any arguments
(e.g., origin my-branch or --force)
63. On a new branch
$ git checkout -b new-branch
Switched to a new branch 'new-branch'
$ git commit -am "my changes"
[new-branch eabe2c9] my changes
1 file changed, 2 insertions(+)
$ git push
fatal: The current branch new-branch has no upstream branch
To push the current branch and set the remote as upstream,
use
git push --set-upstream origin new-branch
$ git push --set-upstream origin new-branch
64. After a rebase
$ git rebase -i master
Switched to a new branch 'new-branch'
$ git push
To github.com:Shopify/some-repo.git
! [rejected] new-branch -> new-branch (non-fast-forward)
error: failed to push some refs to 'github.com:Shopify/
some-repo.git'
hint: Updates were rejected because the tip of your current
branch is behind
$ git push --force
65. Know where you are
Always show the current branch on
your command line prompt (bash):
export PS1="h:W u[033[32m]
$(__git_ps1)[033[00m]$ "
MyComputer:myproject me (my-branch)$
71. Stay fresh
Update your master to the latest
remote without leaving your branch
git pull --rebase --autostash
For git < 2.9, use the git-up gem
gem install git-up
git up
73. Branch prefix shortcuts
git push --delete my-branch
git push --force my-branch
can be shortened to
git push :my-branch
git push +my-branch
(just be careful not to add + by habit)
74. Thank you!
Carlos Duarte Do Nascimento
@chesterbr • http://chester.me
shopify.com/careers
http://slideshare.net/chesterbr
75. This presentation is available under the Creative Commons “by-nc” 3.0 license
(available at https://creativecommons.org/licenses/by-nc/3.0/),
noticing the exceptions below.
Images and text from third parties were included (with due credits wherever possible)
under a fair use assumption (or, for Brazilian media, under Art. 46 of Law 9610/98)
and/or under their respective licenses. Omissions are unintended and corrections
welcome. Such content is excluded from the license above.
GitHub, the GitHub logo and mascot are trademarks of GitHub, Inc.
Shopify and the Shopify logo are trademaks of Shopify, Inc.
The opinions stated here belong solely to the author, not offically representing his
employer’s opinions, nor any of of the persons or companies mentioned in any extent.
Credits And License