<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/2042/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/Using+Git%27s+%27subtree%27+mechanism+for+the+CMake+build+system">Using Git&#39;s &#39;subtree&#39; mechanism for the CMake build system</a></h2>
    <h4>Page  <b>added</b> by             <a href="https://wiki.asterisk.org/wiki/display/~kpfleming">Kevin P. Fleming</a>
    </h4>
         <br/>
    <div class="notificationGreySide">
         <h3><a name="UsingGit%27s%27subtree%27mechanismfortheCMakebuildsystem-Background"></a>Background</h3>

<p>The Asterisk SCF project uses a set of CMake scripts as its build system for C+&#43; components; details on their usage can be found <a href="/wiki/display/TOP/Build+System+%28cmake%29" title="Build System (cmake)">here</a>. These scripts are maintained in their own repository, but need to be included in the source tree for any component that uses them.</p>

<p>In order to minimize the work required for a component developer to keep track of changes and improvements in the build system repository, the <em>subtree</em> mechanism provided by Git can be used. This mechanism allows a Git repository to hold content that originated from a second repository, in a subdirectory, and preserve Git's ability to do merge-tracking for that content. This mechanism works well when the <ins>included</ins> repository's content does not change often; if it does, the Git <em>submodule</em> mechanism might be a better solution. In addition, using the <em>subtree</em> mechanism makes it quite difficult to push changes upstream to the repository for the <ins>included</ins> content; this mechanism should really only be used when that content is going to be treated as <b>read-only</b> in the target repository.</p>

<h3><a name="UsingGit%27s%27subtree%27mechanismfortheCMakebuildsystem-Setup"></a>Setup</h3>

<p>In this example, you have created your own Git repository to hold an Asterisk SCF component, and you'd like to incorporate the Asterisk SCF build system using this mechanism.</p>

<p>The first step is to add a Git <em>remote</em> that points to the build system repository, so its content can be retrieved:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
# git remote add -f cmake git://git.asterisk.org/asterisk-scf/release/cmake
]]></script>
</div></div>
<p>This will add a remote named 'cmake', and fetch its contents. To verify that it had the desired effect, use the  'git branch' command:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
# git branch -a --verbose
]]></script>
</div></div>
<p>This will list the branches (refs) present in the Git repository; you should see a ref named 'remotes/cmake/master', and it should list the commit hash and commit message for the most recent commit in that branch.<br/>
The next step is to prepare the repository to include the content from the 'cmake' remote; first, we'll let Git construct a commit message from the log of the 'cmake' repository, so that all of its history will be visible in this repository's log:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
# git merge --strategy ours --no-commit cmake/master
]]></script>
</div></div>
<p>This command won't change your working tree or index, but if you look in the .git directory, you'll see a MERGE_MSG file with the combined commit message.<br/>
Next, we need Git to actually bring in the content from the 'cmake' repository into a 'cmake' subdirectory:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
# git read-tree --prefix=cmake/ -u cmake/master
]]></script>
</div></div>
<p>After this command is finished, you'll see that you have a 'cmake' subdirectory with the build system files in it, and if you issue a 'git status' command, you'll see that all these files are staged to be committed as well.<br/>
In order to avoid accidentally changing the content of the 'cmake' subdirectory in the future, it should be added to the '.gitignore' file. Edit this file with your editor of choice, and use 'git add' to stage it for commit.<br/>
Finally, it's time to commit these changes:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
# git commit
]]></script>
</div></div>
<p>When your editor opens, you'll see the previously prepared 'merge commit' message ready for your use; edit it if you wish. When the commit completes, your repository is ready to go, and contains a copy of the Asterisk SCF build system.</p>
<h3><a name="UsingGit%27s%27subtree%27mechanismfortheCMakebuildsystem-Updates"></a>Updates</h3>
<p>From time to time, you might want to update the copy of the build system in your component repository; using Git's merge tracking abilities and the <em>subtree</em> merge mechanism, this is very easy to do:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
# git pull --strategy subtree cmake master
]]></script>
</div></div>
<p>This will fetch the most recent content from the 'cmake' repository, then merge in whatever content is present on the 'master' branch in that repository into the branch you have checked out from your repository. Because of the use of the <em>subtree</em> merge mechanism, Git will automatically prefix the paths of all content received from the 'cmake' repository with the prefix you specified when you issued the 'read-tree' command during the setup process.<br/>
Once the 'git pull' operation completes, you can use 'git log' to verify that the changes you wanted have been merged; the log should look just like a normal Git merge operation was performed, because that's exactly what Git did... it just put the content in a different directory than it appears in the source repository.</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/Using+Git%27s+%27subtree%27+mechanism+for+the+CMake+build+system">View Online</a>
              |
       <a href="https://wiki.asterisk.org/wiki/display/TOP/Using+Git%27s+%27subtree%27+mechanism+for+the+CMake+build+system?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
           </div>
</div>
</div>
</div>
</div>
</body>
</html>