<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/2036/1/7/_/styles/combined.css?spaceKey=TOP&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://wiki.asterisk.org/wiki/display/TOP/Git+Hints+and+Usage">Git Hints and Usage</a></h2>
    <h4>Page  <b>added</b> by             <a href="https://wiki.asterisk.org/wiki/display/~dlee">David M. Lee</a>
    </h4>
         <br/>
    <div class="notificationGreySide">
         
<div>
<ul>
    <li><a href='#GitHintsandUsage-Mergingvs.Rebasing'>1. Merging vs. Rebasing</a></li>
<ul>
    <li><a href='#GitHintsandUsage-Knowwhentorebase'>1.1. Know when to rebase</a></li>
    <li><a href='#GitHintsandUsage-Knowwhennottorebase'>1.2. Know when not to rebase</a></li>
    <li><a href='#GitHintsandUsage-Knowyourescaperoutes'>1.3. Know your escape routes</a></li>
    <li><a href='#GitHintsandUsage-Knowyourplan'>1.4. Know your plan</a></li>
</ul>
</ul></div>
<p>Git is not only a powerful tool, but has approximately 6,975 different ways to accomplish any one task.  Sometimes how you go about the task makes a difference, sometimes it doesn't.  This page is to provide some hints for consistent usage.</p>

<h1><a name="GitHintsandUsage-Mergingvs.Rebasing"></a>1. Merging vs. Rebasing</h1>

<p>When you're finished working in a topic branch, you're ready to get your changes into master.  You can choose between <a href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html" class="external-link" rel="nofollow">git merge</a> and <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html" class="external-link" rel="nofollow">git rebase</a>.</p>

<p>While there is some <a href="http://changelog.complete.org/archives/586-rebase-considered-harmful" class="external-link" rel="nofollow">fear about using rebase</a> (and <a href="http://blog.madism.org/index.php/2007/02/25/124-git-rebase-is-not-harmful-it-s-just-_not_-always-the-best-solution-that-s-all" class="external-link" rel="nofollow">rightly so</a>), there are <a href="http://darwinweb.net/articles/the-case-for-git-rebase" class="external-link" rel="nofollow">times where it's appropriate</a>.  When used with care, it can help keep change history clean and manageable.</p>

<h2><a name="GitHintsandUsage-Knowwhentorebase"></a>1.1. Know when to rebase</h2>

<p>The most troubling aspect of rebasing is that it rewrites history.  For a topic branch that you're about to delete because you're moving the changes to master, that's just fine.  For a long-lived branch that needs to live long after the rebase, that can be a problem.</p>

<p>The general rule is that you should not rebase changes that have been pushed to a location where someone else may have pulled them.  If they were to also pull your rebased changes, then git wouldn't recognize the changes as being the same and would attempt to apply the rebased changes on top of the original changes.  <del>Hilarity</del> Panic ensues.</p>

<p>As I said, though, if you're about to delete the topic branch, and the rebased changes are going to be pushed to a different branch (usually master), then rebasing is probably not going to be a problem for you.</p>

<h2><a name="GitHintsandUsage-Knowwhennottorebase"></a>1.2. Know when not to rebase</h2>

<p>In addition to publicly expose branches, there are times when rebasing simply isn't worth it.  If you've been working on your topic branch for some time, it's possible that enough has changed that a rebase operation would require significant conflict resolution in order to complete.  The challenge resolving conflicts with rebase is that you have to resolve them piecemeal, one commit at a time.</p>

<p>The advantage of a merge operation is that you can resolve conflicts of your total merged changes all at once, which could be much simpler.</p>

<h2><a name="GitHintsandUsage-Knowyourescaperoutes"></a>1.3. Know your escape routes</h2>

<p>The scariest thing about rebase is that it rewrites history.  The biggest fear is that you can lose your work should the rebase go awry.  Fortunately, git has several methods to help you out in these situations.</p>

<p>Git keeps a <a href="http://www.kernel.org/pub/software/scm/git/docs/git-reflog.html" class="external-link" rel="nofollow">reflog</a> of commit states, so you can get back to whatever state you were in prior to the rebase.  You can run <tt>git reflog</tt>, look for the commit just prior to your rebase, and <tt>git reset --hard</tt> to that commit to get things back to the way they were.</p>

<h2><a name="GitHintsandUsage-Knowyourplan"></a>1.4. Know your plan</h2>

<p>It's best to know what you're going to do before you start gitting.  Here's my typical command sequence for getting topic branch changes back to master</p>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>I need to double check this the next time I have a meaningful merge.</td></tr></table></div>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: bash; gutter: false"><![CDATA[
# pull latest changes for master
[dlee@dlee-mac repo (master)]$ git pull
# checkout topic-branch
[dlee@dlee-mac repo (master)]$ git checkout topic-branch
# pull latest changes for topic-branch
[dlee@dlee-mac repo (topic-branch)]$ git pull
# rebase onto master.  I usually do this interactively so I can 
# squash, fixup, reorder, etc. my commits
[dlee@dlee-mac repo (topic-branch)]$ git rebase -i master
# assuming all went as planned, go back to master
[dlee@dlee-mac repo (topic-branch)]$ git checkout master
# merge changes from the topic-branch.  should be just a fast-forward
[dlee@dlee-mac repo (master)]$ git merge topic-branch
# push to the remote repo
[dlee@dlee-mac repo (master)]$ git push origin master
# delete the local topic branch
[dlee@dlee-mac repo (master)]$ git branch -d topic-branch
# delete the remote topic branch
[dlee@dlee-mac repo (master)]$ git push integration :topic-branch
]]></script>
</div></div>
    </div>
    <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="https://wiki.asterisk.org/wiki/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
       </div>
       <a href="https://wiki.asterisk.org/wiki/display/TOP/Git+Hints+and+Usage">View Online</a>
              |
       <a href="https://wiki.asterisk.org/wiki/display/TOP/Git+Hints+and+Usage?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
           </div>
</div>
</div>
</div>
</div>
</body>
</html>