CINXE.COM
Git - Replace
<!DOCTYPE html> <html lang="ms"> <head> <meta charset='utf-8'> <meta content='IE=edge,chrome=1' http-equiv='X-UA-Compatible'> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Git - Replace</title> <link href="/favicon.ico" rel='shortcut icon' type='image/x-icon'> <link rel="stylesheet" href="/application.min.css"> <script src="/js/modernizr.js"></script> <script src="/js/modernize.js"></script> </head> <body id="documentation"> <div class="inner"> <header> <a href="/"><img src="/images/logo@2x.png" width="110" height="46" alt="Git" /></a> <span id="tagline"></span> <script type="text/javascript"> const taglines = [ "fast-version-control", "everything-is-local", "distributed-even-if-your-workflow-isnt", "local-branching-on-the-cheap", "distributed-is-the-new-centralized" ]; var tagline = taglines[Math.floor(Math.random() * taglines.length)]; document.getElementById('tagline').innerHTML = '--' + tagline; </script> <form id="search" action="/search/results"> <input id="search-text" name="search" placeholder="Type / to search entire site…" autocomplete="off" type="text" /> </form> <div id="search-results"></div> </header> </div> <div class="inner"> <div id="content-wrapper"> <div tabindex="1" class="sidebar-btn"></div> <aside class="sidebar" id="sidebar"> <nav> <ul> <li> <a href="/about">About</a> <ul> </ul> </li> <li> <a href="/doc" class="active">Documentation</a> <ul class="expanded"> <li> <a href="/docs">Reference</a> </li> <li> <a href="/book" class="active">Book</a> </li> <li> <a href="/videos">Videos</a> </li> <li> <a href="/doc/ext">External Links</a> </li> </ul> </li> <li> <a href="/downloads">Downloads</a> <ul > <li> <a href="/downloads/guis">GUI Clients</a> </li> <li> <a href="/downloads/logos">Logos</a> </li> </ul> </li> <li> <a href="/community">Community</a> </li> </ul> <hr class="sidebar"> <p> This book is available in <a href="/book/en/v2/Git-Tools-Replace">English</a>. </p> <p> Full translation available in <table> <tr><td><a href="/book/az/v2/Git-Al%c9%99tl%c9%99ri-D%c9%99yi%c5%9fdirm%c9%99k">azərbaycan dili</a>,</td></tr> <tr><td><a href="/book/bg">български език</a>,</td></tr> <tr><td><a href="/book/de/v2/Git-Tools-Replace-Ersetzen">Deutsch</a>,</td></tr> <tr><td><a href="/book/es/v2/Herramientas-de-Git-Replace">Español</a>,</td></tr> <tr><td><a href="/book/fr/v2/Utilitaires-Git-Replace">Français</a>,</td></tr> <tr><td><a href="/book/gr">Ελληνικά</a>,</td></tr> <tr><td><a href="/book/ja/v2/Git-%e3%81%ae%e3%81%95%e3%81%be%e3%81%96%e3%81%be%e3%81%aa%e3%83%84%e3%83%bc%e3%83%ab-Git-%e3%82%aa%e3%83%96%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e3%81%ae%e7%bd%ae%e3%81%8d%e6%8f%9b%e3%81%88">日本語</a>,</td></tr> <tr><td><a href="/book/ko/v2/Git-%eb%8f%84%ea%b5%ac-Replace">한국어</a>,</td></tr> <tr><td><a href="/book/nl/v2/Git-Tools-Vervangen">Nederlands</a>,</td></tr> <tr><td><a href="/book/ru/v2/%d0%98%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d1%8b-Git-%d0%97%d0%b0%d0%bc%d0%b5%d0%bd%d0%b0">Русский</a>,</td></tr> <tr><td><a href="/book/sl/v2/Orodja-Git-Zamenjava">Slovenščina</a>,</td></tr> <tr><td><a href="/book/tl/v2/Mga-Git-na-Kasangkapan-Pagpapalit">Tagalog</a>,</td></tr> <tr><td><a href="/book/uk/v2/%d0%86%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b8-Git-%d0%97%d0%b0%d0%bc%d1%96%d0%bd%d0%b0">Українська</a></td></tr> <tr><td><a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e6%9b%bf%e6%8d%a2">简体中文</a>,</td></tr> </table> </p> <p> Partial translations available in <table> <tr><td><a href="/book/cs/v2/Git-Tools-Replace">Čeština</a>,</td></tr> <tr><td><a href="/book/mk/v2/Git-%d0%90%d0%bb%d0%b0%d1%82%d0%ba%d0%b8-%d0%97%d0%b0%d0%bc%d0%b5%d0%bd%d1%83%d0%b2%d0%b0%d1%9a%d0%b5">Македонски</a>,</td></tr> <tr><td><a href="/book/pl/v2/Narz%c4%99dzia-Gita-Replace">Polski</a>,</td></tr> <tr><td><a href="/book/sr/v2/%d0%93%d0%b8%d1%82-%d0%b0%d0%bb%d0%b0%d1%82%d0%b8-%d0%97%d0%b0%d0%bc%d0%b5%d0%bd%d0%b0">Српски</a>,</td></tr> <tr><td><a href="/book/uz/v2/Git-Tools-Replace">Ўзбекча</a>,</td></tr> <tr><td><a href="/book/zh-tw/v2/Git-%e5%b7%a5%e5%85%b7-Replace">繁體中文</a>,</td></tr> </table> </p> <p> Translations started for <table> <tr><td><a href="/book/be/v2/Git-Tools-Replace">Беларуская</a>,</td></tr> <tr><td><a href="/book/fa/v2/Git-Tools-Replace" dir="rtl">فارسی</a>,</td></tr> <tr><td><a href="/book/id/v2/Git-Tools-Replace">Indonesian</a>,</td></tr> <tr><td><a href="/book/it/v2/Git-Tools-Replace">Italiano</a>,</td></tr> <tr><td><a href="/book/ms/v2/Git-Tools-Replace">Bahasa Melayu</a>,</td></tr> <tr><td><a href="/book/pt-br/v2/Git-Tools-Replace">Português (Brasil)</a>,</td></tr> <tr><td><a href="/book/pt-pt/v2/Ferramentas-do-Git-Replace">Português (Portugal)</a>,</td></tr> <tr><td><a href="/book/sv/v2/Git-Tools-Replace">Svenska</a>,</td></tr> <tr><td><a href="/book/tr/v2/Git-Ara%c3%a7lar%c4%b1-Git-Nesnesini-De%c4%9fi%c5%9ftirme">Türkçe</a>.</td></tr> </table> </p> <hr class="sidebar"/> <p> The source of this book is <a href="https://github.com/progit2-ms/progit2">hosted on GitHub.</a></br> Patches, suggestions and comments are welcome. </p> </nav> </aside> <div id="content"> <div id="book-chapters"> <a class="dropdown-trigger" id="book-chapters-trigger" data-panel-id="chapters-dropdown" href="#">Chapters ▾</a> <div class='dropdown-panel' id='chapters-dropdown'> <div class='three-column'> <div class="column-left"> <ol class='book-toc'> <li class='chapter'> <h2>1. <a href="/book/ms/v2/Getting-Started-About-Version-Control">Getting Started</a></h2> <ol> <li> 1.1 <a href="/book/ms/v2/Getting-Started-About-Version-Control">About Version Control</a> </li> <li> 1.2 <a href="/book/ms/v2/Getting-Started-A-Short-History-of-Git">A Short History of Git</a> </li> <li> 1.3 <a href="/book/ms/v2/Getting-Started-What-is-Git%3F">What is Git?</a> </li> <li> 1.4 <a href="/book/ms/v2/Getting-Started-The-Command-Line">The Command Line</a> </li> <li> 1.5 <a href="/book/ms/v2/Getting-Started-Installing-Git">Installing Git</a> </li> <li> 1.6 <a href="/book/ms/v2/Getting-Started-First-Time-Git-Setup">First-Time Git Setup</a> </li> <li> 1.7 <a href="/book/ms/v2/Getting-Started-Getting-Help">Getting Help</a> </li> <li> 1.8 <a href="/book/ms/v2/Getting-Started-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>2. <a href="/book/ms/v2/Git-Basics-Getting-a-Git-Repository">Git Basics</a></h2> <ol> <li> 2.1 <a href="/book/ms/v2/Git-Basics-Getting-a-Git-Repository">Getting a Git Repository</a> </li> <li> 2.2 <a href="/book/ms/v2/Git-Basics-Recording-Changes-to-the-Repository">Recording Changes to the Repository</a> </li> <li> 2.3 <a href="/book/ms/v2/Git-Basics-Viewing-the-Commit-History">Viewing the Commit History</a> </li> <li> 2.4 <a href="/book/ms/v2/Git-Basics-Undoing-Things">Undoing Things</a> </li> <li> 2.5 <a href="/book/ms/v2/Git-Basics-Working-with-Remotes">Working with Remotes</a> </li> <li> 2.6 <a href="/book/ms/v2/Git-Basics-Tagging">Tagging</a> </li> <li> 2.7 <a href="/book/ms/v2/Git-Basics-Git-Aliases">Git Aliases</a> </li> <li> 2.8 <a href="/book/ms/v2/Git-Basics-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>3. <a href="/book/ms/v2/Git-Branching-Branches-in-a-Nutshell">Git Branching</a></h2> <ol> <li> 3.1 <a href="/book/ms/v2/Git-Branching-Branches-in-a-Nutshell">Branches in a Nutshell</a> </li> <li> 3.2 <a href="/book/ms/v2/Git-Branching-Basic-Branching-and-Merging">Basic Branching and Merging</a> </li> <li> 3.3 <a href="/book/ms/v2/Git-Branching-Branch-Management">Branch Management</a> </li> <li> 3.4 <a href="/book/ms/v2/Git-Branching-Branching-Workflows">Branching Workflows</a> </li> <li> 3.5 <a href="/book/ms/v2/Git-Branching-Remote-Branches">Remote Branches</a> </li> <li> 3.6 <a href="/book/ms/v2/Git-Branching-Rebasing">Rebasing</a> </li> <li> 3.7 <a href="/book/ms/v2/Git-Branching-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>4. <a href="/book/ms/v2/Git-on-the-Server-The-Protocols">Git on the Server</a></h2> <ol> <li> 4.1 <a href="/book/ms/v2/Git-on-the-Server-The-Protocols">The Protocols</a> </li> <li> 4.2 <a href="/book/ms/v2/Git-on-the-Server-Getting-Git-on-a-Server">Getting Git on a Server</a> </li> <li> 4.3 <a href="/book/ms/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key">Generating Your SSH Public Key</a> </li> <li> 4.4 <a href="/book/ms/v2/Git-on-the-Server-Setting-Up-the-Server">Setting Up the Server</a> </li> <li> 4.5 <a href="/book/ms/v2/Git-on-the-Server-Git-Daemon">Git Daemon</a> </li> <li> 4.6 <a href="/book/ms/v2/Git-on-the-Server-Smart-HTTP">Smart HTTP</a> </li> <li> 4.7 <a href="/book/ms/v2/Git-on-the-Server-GitWeb">GitWeb</a> </li> <li> 4.8 <a href="/book/ms/v2/Git-on-the-Server-GitLab">GitLab</a> </li> <li> 4.9 <a href="/book/ms/v2/Git-on-the-Server-Third-Party-Hosted-Options">Third Party Hosted Options</a> </li> <li> 4.10 <a href="/book/ms/v2/Git-on-the-Server-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>5. <a href="/book/ms/v2/Distributed-Git-Distributed-Workflows">Distributed Git</a></h2> <ol> <li> 5.1 <a href="/book/ms/v2/Distributed-Git-Distributed-Workflows">Distributed Workflows</a> </li> <li> 5.2 <a href="/book/ms/v2/Distributed-Git-Contributing-to-a-Project">Contributing to a Project</a> </li> <li> 5.3 <a href="/book/ms/v2/Distributed-Git-Maintaining-a-Project">Maintaining a Project</a> </li> <li> 5.4 <a href="/book/ms/v2/Distributed-Git-Summary">Summary</a> </li> </ol> </li> </ol> </div> <div class='column-middle'> <ol class='book-toc'> <li class='chapter'> <h2>6. <a href="/book/ms/v2/GitHub-Account-Setup-and-Configuration">GitHub</a></h2> <ol> <li> 6.1 <a href="/book/ms/v2/GitHub-Account-Setup-and-Configuration">Account Setup and Configuration</a> </li> <li> 6.2 <a href="/book/ms/v2/GitHub-Contributing-to-a-Project">Contributing to a Project</a> </li> <li> 6.3 <a href="/book/ms/v2/GitHub-Maintaining-a-Project">Maintaining a Project</a> </li> <li> 6.4 <a href="/book/ms/v2/GitHub-Managing-an-organization">Managing an organization</a> </li> <li> 6.5 <a href="/book/ms/v2/GitHub-Scripting-GitHub">Scripting GitHub</a> </li> <li> 6.6 <a href="/book/ms/v2/GitHub-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>7. <a href="/book/ms/v2/Git-Tools-Revision-Selection">Git Tools</a></h2> <ol> <li> 7.1 <a href="/book/ms/v2/Git-Tools-Revision-Selection">Revision Selection</a> </li> <li> 7.2 <a href="/book/ms/v2/Git-Tools-Interactive-Staging">Interactive Staging</a> </li> <li> 7.3 <a href="/book/ms/v2/Git-Tools-Stashing-and-Cleaning">Stashing and Cleaning</a> </li> <li> 7.4 <a href="/book/ms/v2/Git-Tools-Signing-Your-Work">Signing Your Work</a> </li> <li> 7.5 <a href="/book/ms/v2/Git-Tools-Searching">Searching</a> </li> <li> 7.6 <a href="/book/ms/v2/Git-Tools-Rewriting-History">Rewriting History</a> </li> <li> 7.7 <a href="/book/ms/v2/Git-Tools-Reset-Demystified">Reset Demystified</a> </li> <li> 7.8 <a href="/book/ms/v2/Git-Tools-Advanced-Merging">Advanced Merging</a> </li> <li> 7.9 <a href="/book/ms/v2/Git-Tools-Rerere">Rerere</a> </li> <li> 7.10 <a href="/book/ms/v2/Git-Tools-Debugging-with-Git">Debugging with Git</a> </li> <li> 7.11 <a href="/book/ms/v2/Git-Tools-Submodules">Submodules</a> </li> <li> 7.12 <a href="/book/ms/v2/Git-Tools-Bundling">Bundling</a> </li> <li> 7.13 <a href="/book/ms/v2/Git-Tools-Replace" class="active">Replace</a> </li> <li> 7.14 <a href="/book/ms/v2/Git-Tools-Credential-Storage">Credential Storage</a> </li> <li> 7.15 <a href="/book/ms/v2/Git-Tools-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>8. <a href="/book/ms/v2/Customizing-Git-Git-Configuration">Customizing Git</a></h2> <ol> <li> 8.1 <a href="/book/ms/v2/Customizing-Git-Git-Configuration">Git Configuration</a> </li> <li> 8.2 <a href="/book/ms/v2/Customizing-Git-Git-Attributes">Git Attributes</a> </li> <li> 8.3 <a href="/book/ms/v2/Customizing-Git-Git-Hooks">Git Hooks</a> </li> <li> 8.4 <a href="/book/ms/v2/Customizing-Git-An-Example-Git-Enforced-Policy">An Example Git-Enforced Policy</a> </li> <li> 8.5 <a href="/book/ms/v2/Customizing-Git-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>9. <a href="/book/ms/v2/Git-and-Other-Systems-Git-as-a-Client">Git and Other Systems</a></h2> <ol> <li> 9.1 <a href="/book/ms/v2/Git-and-Other-Systems-Git-as-a-Client">Git as a Client</a> </li> <li> 9.2 <a href="/book/ms/v2/Git-and-Other-Systems-Migrating-to-Git">Migrating to Git</a> </li> <li> 9.3 <a href="/book/ms/v2/Git-and-Other-Systems-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>10. <a href="/book/ms/v2/Git-Internals-Plumbing-and-Porcelain">Git Internals</a></h2> <ol> <li> 10.1 <a href="/book/ms/v2/Git-Internals-Plumbing-and-Porcelain">Plumbing and Porcelain</a> </li> <li> 10.2 <a href="/book/ms/v2/Git-Internals-Git-Objects">Git Objects</a> </li> <li> 10.3 <a href="/book/ms/v2/Git-Internals-Git-References">Git References</a> </li> <li> 10.4 <a href="/book/ms/v2/Git-Internals-Packfiles">Packfiles</a> </li> <li> 10.5 <a href="/book/ms/v2/Git-Internals-The-Refspec">The Refspec</a> </li> <li> 10.6 <a href="/book/ms/v2/Git-Internals-Transfer-Protocols">Transfer Protocols</a> </li> <li> 10.7 <a href="/book/ms/v2/Git-Internals-Maintenance-and-Data-Recovery">Maintenance and Data Recovery</a> </li> <li> 10.8 <a href="/book/ms/v2/Git-Internals-Environment-Variables">Environment Variables</a> </li> <li> 10.9 <a href="/book/ms/v2/Git-Internals-Summary">Summary</a> </li> </ol> </li> </ol> </div> <div class='column-right'> <ol class='book-toc'> <li class='chapter'> <h2>A1. <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Graphical-Interfaces">Appendix A: Git in Other Environments</a></h2> <ol> <li> A1.1 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Graphical-Interfaces">Graphical Interfaces</a> </li> <li> A1.2 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Visual-Studio">Git in Visual Studio</a> </li> <li> A1.3 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Visual-Studio-Code">Git in Visual Studio Code</a> </li> <li> A1.4 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Git-in-IntelliJ-/-PyCharm-/-WebStorm-/-PhpStorm-/-RubyMine">Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine</a> </li> <li> A1.5 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Sublime-Text">Git in Sublime Text</a> </li> <li> A1.6 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Bash">Git in Bash</a> </li> <li> A1.7 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Zsh">Git in Zsh</a> </li> <li> A1.8 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Git-in-PowerShell">Git in PowerShell</a> </li> <li> A1.9 <a href="/book/ms/v2/Appendix-A:-Git-in-Other-Environments-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>A2. <a href="/book/ms/v2/Appendix-B:-Embedding-Git-in-your-Applications-Command-line-Git">Appendix B: Embedding Git in your Applications</a></h2> <ol> <li> A2.1 <a href="/book/ms/v2/Appendix-B:-Embedding-Git-in-your-Applications-Command-line-Git">Command-line Git</a> </li> <li> A2.2 <a href="/book/ms/v2/Appendix-B:-Embedding-Git-in-your-Applications-Libgit2">Libgit2</a> </li> <li> A2.3 <a href="/book/ms/v2/Appendix-B:-Embedding-Git-in-your-Applications-JGit">JGit</a> </li> <li> A2.4 <a href="/book/ms/v2/Appendix-B:-Embedding-Git-in-your-Applications-go-git">go-git</a> </li> <li> A2.5 <a href="/book/ms/v2/Appendix-B:-Embedding-Git-in-your-Applications-Dulwich">Dulwich</a> </li> </ol> </li> <li class='chapter'> <h2>A3. <a href="/book/ms/v2/Appendix-C:-Git-Commands-Setup-and-Config">Appendix C: Git Commands</a></h2> <ol> <li> A3.1 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Setup-and-Config">Setup and Config</a> </li> <li> A3.2 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Getting-and-Creating-Projects">Getting and Creating Projects</a> </li> <li> A3.3 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Basic-Snapshotting">Basic Snapshotting</a> </li> <li> A3.4 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Branching-and-Merging">Branching and Merging</a> </li> <li> A3.5 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Sharing-and-Updating-Projects">Sharing and Updating Projects</a> </li> <li> A3.6 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Inspection-and-Comparison">Inspection and Comparison</a> </li> <li> A3.7 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Debugging">Debugging</a> </li> <li> A3.8 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Patching">Patching</a> </li> <li> A3.9 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Email">Email</a> </li> <li> A3.10 <a href="/book/ms/v2/Appendix-C:-Git-Commands-External-Systems">External Systems</a> </li> <li> A3.11 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Administration">Administration</a> </li> <li> A3.12 <a href="/book/ms/v2/Appendix-C:-Git-Commands-Plumbing-Commands">Plumbing Commands</a> </li> </ol> </li> </ol> </div> </div> </div> <span class="light" id="edition"> 2nd Edition </span> </div> <div id="main" data-pagefind-filter="category:book" data-pagefind-meta="category:Book" data-pagefind-weight="0.05" data-pagefind-body class="book edition2"> <h1>7.13 Git Tools - Replace</h1> <div> <h2 id="_replace">Replace</h2> <div class="paragraph"> <p>As we’ve emphasized before, the objects in Git’s object database are unchangeable, but Git does provide an interesting way to <em>pretend</em> to replace objects in its database with other objects.</p> </div> <div class="paragraph"> <p>The <code>replace</code> command lets you specify an object in Git and say "every time you refer to <em>this</em> object, pretend it’s a <em>different</em> object". This is most commonly useful for replacing one commit in your history with another one without having to rebuild the entire history with, say, <code>git filter-branch</code>.</p> </div> <div class="paragraph"> <p>For example, let’s say you have a huge code history and want to split your repository into one short history for new developers and one much longer and larger history for people interested in data mining. You can graft one history onto the other by "replacing" the earliest commit in the new line with the latest commit on the older one. This is nice because it means that you don’t actually have to rewrite every commit in the new history, as you would normally have to do to join them together (because the parentage affects the SHA-1s).</p> </div> <div class="paragraph"> <p>Let’s try this out. Let’s take an existing repository, split it into two repositories, one recent and one historical, and then we’ll see how we can recombine them without modifying the recent repositories SHA-1 values via <code>replace</code>.</p> </div> <div class="paragraph"> <p>We’ll use a simple repository with five simple commits:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git log --oneline ef989d8 Fifth commit c6e1e95 Fourth commit 9c68fdc Third commit 945704c Second commit c1822cf First commit</code></pre> </div> </div> <div class="paragraph"> <p>We want to break this up into two lines of history. One line goes from commit one to commit four - that will be the historical one. The second line will just be commits four and five - that will be the recent history.</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/ms/v2/images/replace1.png" alt="replace1"> </div> </div> <div class="paragraph"> <p>Well, creating the historical history is easy, we can just put a branch in the history and then push that branch to the <code>master</code> branch of a new remote repository.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git branch history c6e1e95 $ git log --oneline --decorate ef989d8 (HEAD, master) Fifth commit c6e1e95 (history) Fourth commit 9c68fdc Third commit 945704c Second commit c1822cf First commit</code></pre> </div> </div> <div class="imageblock"> <div class="content"> <img src="/book/ms/v2/images/replace2.png" alt="replace2"> </div> </div> <div class="paragraph"> <p>Now we can push the new <code>history</code> branch to the <code>master</code> branch of our new repository:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git remote add project-history https://github.com/schacon/project-history $ git push project-history history:master Counting objects: 12, done. Delta compression using up to 2 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (12/12), 907 bytes, done. Total 12 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (12/12), done. To git@github.com:schacon/project-history.git * [new branch] history -> master</code></pre> </div> </div> <div class="paragraph"> <p>OK, so our history is published. Now the harder part is truncating our recent history down so it’s smaller. We need an overlap so we can replace a commit in one with an equivalent commit in the other, so we’re going to truncate this to just commits four and five (so commit four overlaps).</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git log --oneline --decorate ef989d8 (HEAD, master) Fifth commit c6e1e95 (history) Fourth commit 9c68fdc Third commit 945704c Second commit c1822cf First commit</code></pre> </div> </div> <div class="paragraph"> <p>It’s useful in this case to create a base commit that has instructions on how to expand the history, so other developers know what to do if they hit the first commit in the truncated history and need more. So, what we’re going to do is create an initial commit object as our base point with instructions, then rebase the remaining commits (four and five) on top of it.</p> </div> <div class="paragraph"> <p>To do that, we need to choose a point to split at, which for us is the third commit, which is <code>9c68fdc</code> in SHA-speak. So, our base commit will be based off of that tree. We can create our base commit using the <code>commit-tree</code> command, which just takes a tree and will give us a brand new, parentless commit object SHA-1 back.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ echo 'Get history from blah blah blah' | git commit-tree 9c68fdc^{tree} 622e88e9cbfbacfb75b5279245b9fb38dfea10cf</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content"> <div class="paragraph"> <p>The <code>commit-tree</code> command is one of a set of commands that are commonly referred to as 'plumbing' commands. These are commands that are not generally meant to be used directly, but instead are used by <strong>other</strong> Git commands to do smaller jobs. On occasions when we’re doing weirder things like this, they allow us to do really low-level things but are not meant for daily use. You can read more about plumbing commands in <a href="/book/ms/v2/ch00/_plumbing_porcelain">Plumbing and Porcelain</a>.</p> </div> </td> </tr> </table> </div> <div class="imageblock"> <div class="content"> <img src="/book/ms/v2/images/replace3.png" alt="replace3"> </div> </div> <div class="paragraph"> <p>OK, so now that we have a base commit, we can rebase the rest of our history on top of that with <code>git rebase --onto</code>. The <code>--onto</code> argument will be the SHA-1 we just got back from <code>commit-tree</code> and the rebase point will be the third commit (the parent of the first commit we want to keep, <code>9c68fdc</code>):</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git rebase --onto 622e88 9c68fdc First, rewinding head to replay your work on top of it... Applying: fourth commit Applying: fifth commit</code></pre> </div> </div> <div class="imageblock"> <div class="content"> <img src="/book/ms/v2/images/replace4.png" alt="replace4"> </div> </div> <div class="paragraph"> <p>OK, so now we’ve re-written our recent history on top of a throw away base commit that now has instructions in it on how to reconstitute the entire history if we wanted to. We can push that new history to a new project and now when people clone that repository, they will only see the most recent two commits and then a base commit with instructions.</p> </div> <div class="paragraph"> <p>Let’s now switch roles to someone cloning the project for the first time who wants the entire history. To get the history data after cloning this truncated repository, one would have to add a second remote for the historical repository and fetch:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git clone https://github.com/schacon/project $ cd project $ git log --oneline master e146b5f Fifth commit 81a708d Fourth commit 622e88e Get history from blah blah blah $ git remote add project-history https://github.com/schacon/project-history $ git fetch project-history From https://github.com/schacon/project-history * [new branch] master -> project-history/master</code></pre> </div> </div> <div class="paragraph"> <p>Now the collaborator would have their recent commits in the <code>master</code> branch and the historical commits in the <code>project-history/master</code> branch.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git log --oneline master e146b5f Fifth commit 81a708d Fourth commit 622e88e Get history from blah blah blah $ git log --oneline project-history/master c6e1e95 Fourth commit 9c68fdc Third commit 945704c Second commit c1822cf First commit</code></pre> </div> </div> <div class="paragraph"> <p>To combine them, you can simply call <code>git replace</code> with the commit you want to replace and then the commit you want to replace it with. So we want to replace the "fourth" commit in the <code>master</code> branch with the "fourth" commit in the <code>project-history/master</code> branch:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git replace 81a708d c6e1e95</code></pre> </div> </div> <div class="paragraph"> <p>Now, if you look at the history of the <code>master</code> branch, it appears to look like this:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git log --oneline master e146b5f Fifth commit 81a708d Fourth commit 9c68fdc Third commit 945704c Second commit c1822cf First commit</code></pre> </div> </div> <div class="paragraph"> <p>Cool, right? Without having to change all the SHA-1s upstream, we were able to replace one commit in our history with an entirely different commit and all the normal tools (<code>bisect</code>, <code>blame</code>, etc) will work how we would expect them to.</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/ms/v2/images/replace5.png" alt="replace5"> </div> </div> <div class="paragraph"> <p>Interestingly, it still shows <code>81a708d</code> as the SHA-1, even though it’s actually using the <code>c6e1e95</code> commit data that we replaced it with. Even if you run a command like <code>cat-file</code>, it will show you the replaced data:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git cat-file -p 81a708d tree 7bc544cf438903b65ca9104a1e30345eee6c083d parent 9c68fdceee073230f19ebb8b5e7fc71b479c0252 author Scott Chacon <schacon@gmail.com> 1268712581 -0700 committer Scott Chacon <schacon@gmail.com> 1268712581 -0700 fourth commit</code></pre> </div> </div> <div class="paragraph"> <p>Remember that the actual parent of <code>81a708d</code> was our placeholder commit (<code>622e88e</code>), not <code>9c68fdce</code> as it states here.</p> </div> <div class="paragraph"> <p>Another interesting thing is that this data is kept in our references:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git for-each-ref e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/heads/master c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/remotes/history/master e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/HEAD e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/master c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/replace/81a708dd0e167a3f691541c7a6463343bc457040</code></pre> </div> </div> <div class="paragraph"> <p>This means that it’s easy to share our replacement with others, because we can push this to our server and other people can easily download it. This is not that helpful in the history grafting scenario we’ve gone over here (since everyone would be downloading both histories anyhow, so why separate them?) but it can be useful in other circumstances.</p> </div> <div id="nav"><a href="/book/ms/v2/Git-Tools-Bundling">prev</a> | <a href="/book/ms/v2/Git-Tools-Credential-Storage">next</a></div> </div> </div> </div> </div> <footer> <div class="site-source"> <a href="/site">About this site</a><br> Patches, suggestions, and comments are welcome. </div> <div class="sfc-member"> Git is a member of <a href="/sfc">Software Freedom Conservancy</a> </div> </footer> <a href="#top" class="no-js scrollToTop" id="scrollToTop" data-label="Scroll to top"> <img src="/images/icons/chevron-up@2x.png" width="20" height="20" alt="scroll-to-top"/> </a> <script src="/js/jquery-1.7.1.min.js"></script> <script src="/js/jquery-ui-1.8.18.custom.min.js"></script> <script src="/js/jquery.defaultvalue.js"></script> <script src="/js/session.min.js"></script> <script src="/js/application.min.js"></script> </div> </body> </html>