<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+Workflow+%28draft+for+comments%29">Git Workflow (draft for comments)</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~dlee">David M. Lee</a>
    </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >[dlee@dlee-mac sip (master)]$ git fetch integration <br>{code} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">* You can then use the {{integration}} remote the same way you would use the {{origin}} remote. <br>{code:bash} <br>[dlee@dlee-mac sip (master)]$ git push integration master:new-branch <br>[dlee@dlee-mac sip (master)]$ git checkout new-branch <br>Branch route_async set up to track remote branch new-branch from integration. <br>Switched to a new branch &#39;new-branch&#39; <br>{code} <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h3. Typical Developer Workflow <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <div>
<ul>
    <li><a href='#GitWorkflow%28draftforcomments%29-Overview'>Overview</a></li>
    <li><a href='#GitWorkflow%28draftforcomments%29-Repositoryorganization'>Repository organization</a></li>
<ul>
    <li><a href='#GitWorkflow%28draftforcomments%29-TeamRepositories'>Team Repositories</a></li>
    <li><a href='#GitWorkflow%28draftforcomments%29-IntegrationRepositories'>Integration Repositories</a></li>
    <li><a href='#GitWorkflow%28draftforcomments%29-ReleaseRepositories'>Release Repositories</a></li>
</ul>
    <li><a href='#GitWorkflow%28draftforcomments%29-Workingwithmultiplerepositories'>Working with multiple repositories</a></li>
    <li><a href='#GitWorkflow%28draftforcomments%29-TypicalDeveloperWorkflow'>Typical Developer Workflow</a></li>
</ul></div>

<h3><a name="GitWorkflow%28draftforcomments%29-Overview"></a>Overview</h3>
<p>This page describes how source code is moved among the various repositories of Asterisk SCF on git.asterisk.org </p>

<h3><a name="GitWorkflow%28draftforcomments%29-Repositoryorganization"></a>Repository organization</h3>

<p>Asterisk SCF is made up a variety of distributed components and their APIs. The APIs are specified independently from the actual components that implement them. This allows alternate representations of specific functional components to coexist without ambiguity as to the interfaces such a component is expected to present to the system. Having multiple components that could be versioned / released based on component-specific needs influenced our decision to use multiple repositories. </p>

<p>In addition to having a variety of components, each with their own repository, our chosen workflow is based on a set of 3 categories of repositories:</p>
<h4><a name="GitWorkflow%28draftforcomments%29-TeamRepositories"></a>Team Repositories </h4>
<p>The Team Repositories represent a private sandbox for each contributor. As a matter of standard practice, no other developer will be forking these repositories, so the developer owning a given repository is perfectly free to force rebases or whatever else he wishes to do. It is a perfect place for nightly backups of work-in-progress. Developers can also add /private/ to their repository name and no other developer (except for git server admins) will even be able to view the code. </p>

<p>Fisheye will not be linked to any of the code in the team repositories. Team-member-owned repositories that are not designated as private can be cloned by other developers, but other developers will not be able to push changes into repositories they don't own. </p>

<p>Examples of Team repositories:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>/team/dlee/cmake
/team/dlee/slice
/team/ken.hunt/routing.net
/team/ken.hunt/private/foobar
/team/kpfleming/private/slicing
</pre>
</div></div>

<p>These examples show three developers having team repositories. Developer "ken.hunt" has one private repository (/foobar), and one that can be cloned by other developers (routing.net).</p>

<h4><a name="GitWorkflow%28draftforcomments%29-IntegrationRepositories"></a>Integration Repositories</h4>
<p>These repositories are where formal reviews are held. Developers stage feature-specific branches and schedule reviews of the code directly in those branches. These repositories are periodically (every few minutes) scanned by Fisheye, for code browsing and code reviews.  You can see this at <a href="http://code.asterisk.org" class="external-link" rel="nofollow">http://code.asterisk.org</a>.</p>

<p>Examples of Integration Repositories:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>/asterisk-scf/integration/bridging/
/asterisk-scf/integration/routing/
/asterisk-scf/integration/sip/
/asterisk-scf/integration/slice/
/asterisk-scf/integration/gitall/
</pre>
</div></div>

<p>These examples show repositories for three specific components (/bridging, /routing, /sip) and one repository for the Asterisk SCF core APIs (/slice). The /gitall repository is a special repository that contains useful tools for working with the multiple repositories of Asterisk SCF. The gitall-asterisk-scf.sh found in the /gitall repo will clone the Release repositories of all the components and the core API to make it easy for developers to do integrated builds. </p>

<h4><a name="GitWorkflow%28draftforcomments%29-ReleaseRepositories"></a>Release Repositories</h4>
<p>This is where the latest integrated release of the code is maintained. Once code in an integration repository branch has been reviewed, that branch should be rebased onto the related release repository's master branch. Automated tests are executed on the release repositories. </p>

<p>Examples of Release Repositories:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>/asterisk-scf/release/bridging/
/asterisk-scf/release/routing/
/asterisk-scf/release/sip/
/asterisk-scf/release/slice/
/asterisk-scf/release/design/
</pre>
</div></div>

<p>These examples show the corresponding release repositories to the three components and API that were shown in the Integration examples. It also shows the /design branch which is used to maintain design artifacts such as UML models and system diagrams. </p>

<p>Tags are applied within the Release Repositories' master branches to track major/minor version number changes, and probably release candidates and other such state changes. </p>

<h3><a name="GitWorkflow%28draftforcomments%29-Workingwithmultiplerepositories"></a>Working with multiple repositories</h3>

<p>It can be a bit confusing to know what to do with all of these repositories.  If your git-fu is very strong, you probably don't have a problem.  Most normal people, however, need some guidance.</p>

<ul>
        <li>When you clone, clone the release repositories.  This is what the <tt>gitall-asterisk-scf.sh</tt> does anyways.</li>
        <li>Add the corresponding integration repo as a remote named <tt>integration</tt>.  Then you can refer to it by name instead of by URL.  This will need to be done per-component.  For example, the command to add the integration remote to the sip component and pull down its remote branches:
<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[
[dlee@dlee-mac sip (master)]$ git remote add integration git://git.asterisk.org/asterisk-scf/integration/sip
[dlee@dlee-mac sip (master)]$ git fetch integration
]]></script>
</div></div></li>
        <li>You can then use the <tt>integration</tt> remote the same way you would use the <tt>origin</tt> remote.
<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[
[dlee@dlee-mac sip (master)]$ git push integration master:new-branch
[dlee@dlee-mac sip (master)]$ git checkout new-branch
Branch route_async set up to track remote branch new-branch from integration.
Switched to a new branch 'new-branch'
]]></script>
</div></div></li>
</ul>


<h3><a name="GitWorkflow%28draftforcomments%29-TypicalDeveloperWorkflow"></a>Typical Developer Workflow</h3>
<p>The typical developer workflow would be something like this for developer joe making "changeX" to a component:</p>
<ol>
        <li>Developer runs gitall to pull the Release Repositories' current state</li>
        <li>If the change is involved (taking multiple days) the developer would create their own team/changeX repo. Nightly work would be pushed here.</li>
        <li>Developer would make changes to the component.</li>
        <li>When ready, the developer would create a new branch in the relevant integration repo and push their changes.</li>
        <li>Developer schedules code review.</li>
        <li>Developer incorporates changes required by code review.</li>
        <li>Developer integrates his reviewed changes to the Release Repository's master branch via a rebase operation.</li>
</ol>


<p>This last item (integration via a rebase as opposed to merge) merits further discussion. If you have read this article:</p>

<ul>
        <li><a href="http://blog.experimentalworks.net/2009/03/merge-vs-rebase-a-deep-dive-into-the-mysteries-of-revision-control/" class="external-link" rel="nofollow">http://blog.experimentalworks.net/2009/03/merge-vs-rebase-a-deep-dive-into-the-mysteries-of-revision-control/</a></li>
</ul>


<p>then you have come away with a rule that you should never rebase a branch that you have pulled or that you have pushed. Issues such as multiple commits could come into play. However, if we follow a convention where the feature-specific branches in the Integration Repositories are only created for reviews, not so that multiple developers can make commits, then we are following the spirit of the article. </p>

    </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+Workflow+%28draft+for+comments%29">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=9568530&revisedVersion=15&originalVersion=14">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Git+Workflow+%28draft+for+comments%29?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>