CINXE.COM
Git - 记录每次更新到仓库
<!DOCTYPE html> <html lang="zh"> <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 - 记录每次更新到仓库</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-Basics-Recording-Changes-to-the-Repository">English</a>. </p> <p> Full translation available in <table> <tr><td><a href="/book/az/v2/Git%e2%80%99in-%c6%8fsaslar%c4%b1-Depoda-D%c9%99yi%c5%9fiklikl%c9%99rin-Qeyd-Edilm%c9%99si">azərbaycan dili</a>,</td></tr> <tr><td><a href="/book/bg/v2/%d0%9e%d1%81%d0%bd%d0%be%d0%b2%d0%b8-%d0%bd%d0%b0-Git-%d0%97%d0%b0%d0%bf%d0%b8%d1%81-%d0%bd%d0%b0-%d0%bf%d1%80%d0%be%d0%bc%d0%b5%d0%bd%d0%b8-%d0%b2-%d1%85%d1%80%d0%b0%d0%bd%d0%b8%d0%bb%d0%b8%d1%89%d0%b5%d1%82%d0%be">български език</a>,</td></tr> <tr><td><a href="/book/de/v2/Git-Grundlagen-%c3%84nderungen-nachverfolgen-und-im-Repository-speichern">Deutsch</a>,</td></tr> <tr><td><a href="/book/es/v2/Fundamentos-de-Git-Guardando-cambios-en-el-Repositorio">Español</a>,</td></tr> <tr><td><a href="/book/fr/v2/Les-bases-de-Git-Enregistrer-des-modifications-dans-le-d%c3%a9p%c3%b4t">Français</a>,</td></tr> <tr><td><a href="/book/gr/v2/%ce%a4%ce%b1-%ce%b8%ce%b5%ce%bc%ce%b5%ce%bb%ce%b9%cf%8e%ce%b4%ce%b7-%cf%83%cf%84%ce%bf%ce%b9%cf%87%ce%b5%ce%af%ce%b1-%cf%84%ce%bf%cf%85-Git-%ce%9a%ce%b1%cf%84%ce%b1%ce%b3%cf%81%ce%b1%cf%86%ce%ae-%ce%b1%ce%bb%ce%bb%ce%b1%ce%b3%cf%8e%ce%bd-%cf%83%cf%84%ce%bf-%ce%b1%cf%80%ce%bf%ce%b8%ce%b5%cf%84%ce%ae%cf%81%ce%b9%ce%bf">Ελληνικά</a>,</td></tr> <tr><td><a href="/book/ja/v2/Git-%e3%81%ae%e5%9f%ba%e6%9c%ac-%e5%a4%89%e6%9b%b4%e5%86%85%e5%ae%b9%e3%81%ae%e3%83%aa%e3%83%9d%e3%82%b8%e3%83%88%e3%83%aa%e3%81%b8%e3%81%ae%e8%a8%98%e9%8c%b2">日本語</a>,</td></tr> <tr><td><a href="/book/ko/v2/Git%ec%9d%98-%ea%b8%b0%ec%b4%88-%ec%88%98%ec%a0%95%ed%95%98%ea%b3%a0-%ec%a0%80%ec%9e%a5%ec%86%8c%ec%97%90-%ec%a0%80%ec%9e%a5%ed%95%98%ea%b8%b0">한국어</a>,</td></tr> <tr><td><a href="/book/nl/v2/Git-Basics-Wijzigingen-aan-de-repository-vastleggen">Nederlands</a>,</td></tr> <tr><td><a href="/book/ru/v2/%d0%9e%d1%81%d0%bd%d0%be%d0%b2%d1%8b-Git-%d0%97%d0%b0%d0%bf%d0%b8%d1%81%d1%8c-%d0%b8%d0%b7%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d0%b9-%d0%b2-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d0%b9">Русский</a>,</td></tr> <tr><td><a href="/book/sl/v2/Osnove-Git-Snemanje-sprememb-v-repozitorij">Slovenščina</a>,</td></tr> <tr><td><a href="/book/tl/v2/Mga-Pangunahing-Kaalaman-sa-Git-Pagtatala-ng-mga-Pagbabago-sa-Repositoryo">Tagalog</a>,</td></tr> <tr><td><a href="/book/uk/v2/%d0%9e%d1%81%d0%bd%d0%be%d0%b2%d0%b8-Git-%d0%97%d0%b0%d0%bf%d0%b8%d1%81-%d0%b7%d0%bc%d1%96%d0%bd-%d0%b4%d0%be-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d1%96%d1%8f">Українська</a></td></tr> <tr><td><a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e8%ae%b0%e5%bd%95%e6%af%8f%e6%ac%a1%e6%9b%b4%e6%96%b0%e5%88%b0%e4%bb%93%e5%ba%93">简体中文</a>,</td></tr> </table> </p> <p> Partial translations available in <table> <tr><td><a href="/book/cs/v2/Z%c3%a1klady-pr%c3%a1ce-se-syst%c3%a9mem-Git-Nahr%c3%a1v%c3%a1n%c3%ad-zm%c4%9bn-do-repozit%c3%a1%c5%99e">Čeština</a>,</td></tr> <tr><td><a href="/book/mk/v2/%d0%9e%d1%81%d0%bd%d0%be%d0%b2%d0%b8%d1%82%d0%b5-%d0%bd%d0%b0-Git-%d0%a1%d0%bd%d0%b8%d0%bc%d0%b0%d1%9a%d0%b5-%d0%bd%d0%b0-%d0%bf%d1%80%d0%be%d0%bc%d0%b5%d0%bd%d0%b8-%d0%b2%d0%be-%d1%81%d0%ba%d0%bb%d0%b0%d0%b4%d0%b8%d1%88%d1%82%d0%b5%d1%82%d0%be">Македонски</a>,</td></tr> <tr><td><a href="/book/pl/v2/Podstawy-Gita-Rejestrowanie-zmian-w-repozytorium">Polski</a>,</td></tr> <tr><td><a href="/book/sr/v2/%d0%9e%d1%81%d0%bd%d0%be%d0%b2%d0%b5-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%b0-%d0%93%d0%b8%d1%82-%d0%a1%d0%bd%d0%b8%d0%bc%d0%b0%d1%9a%d0%b5-%d0%bf%d1%80%d0%be%d0%bc%d0%b5%d0%bd%d0%b0-%d0%bd%d0%b0%d0%b4-%d1%80%d0%b5%d0%bf%d0%be%d0%b7%d0%b8%d1%82%d0%be%d1%80%d0%b8%d1%98%d1%83%d0%bc%d0%be%d0%bc">Српски</a>,</td></tr> <tr><td><a href="/book/uz/v2/Git-%d0%b0%d1%81%d0%be%d1%81%d0%bb%d0%b0%d1%80%d0%b8-%d0%8e%d0%b7%d0%b3%d0%b0%d1%80%d0%b8%d1%88%d0%bb%d0%b0%d1%80%d0%bd%d0%b8-%d0%be%d0%bc%d0%b1%d0%be%d1%80%d0%b3%d0%b0-%d1%91%d0%b7%d0%b8%d1%88">Ўзбекча</a>,</td></tr> <tr><td><a href="/book/zh-tw/v2/Git-%e5%9f%ba%e7%a4%8e-%e7%b4%80%e9%8c%84%e8%ae%8a%e6%9b%b4%e5%88%b0%e7%89%88%e6%9c%ac%e5%ba%ab%e4%b8%ad">繁體中文</a>,</td></tr> </table> </p> <p> Translations started for <table> <tr><td><a href="/book/be/v2/Git-Basics-Recording-Changes-to-the-Repository">Беларуская</a>,</td></tr> <tr><td><a href="/book/fa/v2/%d9%85%d9%82%d8%af%d9%85%d8%a7%d8%aa-%da%af%db%8c%d8%aa-%d8%ab%d8%a8%d8%aa-%d8%aa%d8%ba%db%8c%db%8c%d8%b1%d8%a7%d8%aa-%d8%af%d8%b1-%d9%85%d8%ae%d8%b2%d9%86" dir="rtl">فارسی</a>,</td></tr> <tr><td><a href="/book/id/v2/Git-Basics-Recording-Changes-to-the-Repository">Indonesian</a>,</td></tr> <tr><td><a href="/book/it/v2/Git-Basics-Recording-Changes-to-the-Repository">Italiano</a>,</td></tr> <tr><td><a href="/book/ms/v2/Git-Basics-Recording-Changes-to-the-Repository">Bahasa Melayu</a>,</td></tr> <tr><td><a href="/book/pt-br/v2/Fundamentos-de-Git-Gravando-Altera%c3%a7%c3%b5es-em-Seu-Reposit%c3%b3rio">Português (Brasil)</a>,</td></tr> <tr><td><a href="/book/pt-pt/v2/No%c3%a7%c3%b5es-B%c3%a1sicas-do-Git-Recording-Changes-to-the-Repository">Português (Portugal)</a>,</td></tr> <tr><td><a href="/book/sv/v2/Grunder-i-Git-Spara-%c3%a4ndringar-till-f%c3%b6rvaret">Svenska</a>,</td></tr> <tr><td><a href="/book/tr/v2/Git-Temelleri-De%c4%9fi%c5%9fikliklerin-Repoya-Kaydedilmesi">Türkçe</a>.</td></tr> </table> </p> <hr class="sidebar"/> <p> The source of this book is <a href="https://github.com/progit/progit2-zh">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/zh/v2/%e8%b5%b7%e6%ad%a5-%e5%85%b3%e4%ba%8e%e7%89%88%e6%9c%ac%e6%8e%a7%e5%88%b6">起步</a></h2> <ol> <li> 1.1 <a href="/book/zh/v2/%e8%b5%b7%e6%ad%a5-%e5%85%b3%e4%ba%8e%e7%89%88%e6%9c%ac%e6%8e%a7%e5%88%b6">关于版本控制</a> </li> <li> 1.2 <a href="/book/zh/v2/%e8%b5%b7%e6%ad%a5-Git-%e7%ae%80%e5%8f%b2">Git 简史</a> </li> <li> 1.3 <a href="/book/zh/v2/%e8%b5%b7%e6%ad%a5-Git-%e6%98%af%e4%bb%80%e4%b9%88%ef%bc%9f">Git 是什么?</a> </li> <li> 1.4 <a href="/book/zh/v2/%e8%b5%b7%e6%ad%a5-%e5%91%bd%e4%bb%a4%e8%a1%8c">命令行</a> </li> <li> 1.5 <a href="/book/zh/v2/%e8%b5%b7%e6%ad%a5-%e5%ae%89%e8%a3%85-Git">安装 Git</a> </li> <li> 1.6 <a href="/book/zh/v2/%e8%b5%b7%e6%ad%a5-%e5%88%9d%e6%ac%a1%e8%bf%90%e8%a1%8c-Git-%e5%89%8d%e7%9a%84%e9%85%8d%e7%bd%ae">初次运行 Git 前的配置</a> </li> <li> 1.7 <a href="/book/zh/v2/%e8%b5%b7%e6%ad%a5-%e8%8e%b7%e5%8f%96%e5%b8%ae%e5%8a%a9">获取帮助</a> </li> <li> 1.8 <a href="/book/zh/v2/%e8%b5%b7%e6%ad%a5-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>2. <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e8%8e%b7%e5%8f%96-Git-%e4%bb%93%e5%ba%93">Git 基础</a></h2> <ol> <li> 2.1 <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e8%8e%b7%e5%8f%96-Git-%e4%bb%93%e5%ba%93">获取 Git 仓库</a> </li> <li> 2.2 <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e8%ae%b0%e5%bd%95%e6%af%8f%e6%ac%a1%e6%9b%b4%e6%96%b0%e5%88%b0%e4%bb%93%e5%ba%93" class="active">记录每次更新到仓库</a> </li> <li> 2.3 <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e6%9f%a5%e7%9c%8b%e6%8f%90%e4%ba%a4%e5%8e%86%e5%8f%b2">查看提交历史</a> </li> <li> 2.4 <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e6%92%a4%e6%b6%88%e6%93%8d%e4%bd%9c">撤消操作</a> </li> <li> 2.5 <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e8%bf%9c%e7%a8%8b%e4%bb%93%e5%ba%93%e7%9a%84%e4%bd%bf%e7%94%a8">远程仓库的使用</a> </li> <li> 2.6 <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e6%89%93%e6%a0%87%e7%ad%be">打标签</a> </li> <li> 2.7 <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-Git-%e5%88%ab%e5%90%8d">Git 别名</a> </li> <li> 2.8 <a href="/book/zh/v2/Git-%e5%9f%ba%e7%a1%80-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>3. <a href="/book/zh/v2/Git-%e5%88%86%e6%94%af-%e5%88%86%e6%94%af%e7%ae%80%e4%bb%8b">Git 分支</a></h2> <ol> <li> 3.1 <a href="/book/zh/v2/Git-%e5%88%86%e6%94%af-%e5%88%86%e6%94%af%e7%ae%80%e4%bb%8b">分支简介</a> </li> <li> 3.2 <a href="/book/zh/v2/Git-%e5%88%86%e6%94%af-%e5%88%86%e6%94%af%e7%9a%84%e6%96%b0%e5%bb%ba%e4%b8%8e%e5%90%88%e5%b9%b6">分支的新建与合并</a> </li> <li> 3.3 <a href="/book/zh/v2/Git-%e5%88%86%e6%94%af-%e5%88%86%e6%94%af%e7%ae%a1%e7%90%86">分支管理</a> </li> <li> 3.4 <a href="/book/zh/v2/Git-%e5%88%86%e6%94%af-%e5%88%86%e6%94%af%e5%bc%80%e5%8f%91%e5%b7%a5%e4%bd%9c%e6%b5%81">分支开发工作流</a> </li> <li> 3.5 <a href="/book/zh/v2/Git-%e5%88%86%e6%94%af-%e8%bf%9c%e7%a8%8b%e5%88%86%e6%94%af">远程分支</a> </li> <li> 3.6 <a href="/book/zh/v2/Git-%e5%88%86%e6%94%af-%e5%8f%98%e5%9f%ba">变基</a> </li> <li> 3.7 <a href="/book/zh/v2/Git-%e5%88%86%e6%94%af-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>4. <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-%e5%8d%8f%e8%ae%ae">服务器上的 Git</a></h2> <ol> <li> 4.1 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-%e5%8d%8f%e8%ae%ae">协议</a> </li> <li> 4.2 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-%e5%9c%a8%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e6%90%ad%e5%bb%ba-Git">在服务器上搭建 Git</a> </li> <li> 4.3 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-%e7%94%9f%e6%88%90-SSH-%e5%85%ac%e9%92%a5">生成 SSH 公钥</a> </li> <li> 4.4 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-%e9%85%8d%e7%bd%ae%e6%9c%8d%e5%8a%a1%e5%99%a8">配置服务器</a> </li> <li> 4.5 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-Git-%e5%ae%88%e6%8a%a4%e8%bf%9b%e7%a8%8b">Git 守护进程</a> </li> <li> 4.6 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-Smart-HTTP">Smart HTTP</a> </li> <li> 4.7 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-GitWeb">GitWeb</a> </li> <li> 4.8 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-GitLab">GitLab</a> </li> <li> 4.9 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-%e7%ac%ac%e4%b8%89%e6%96%b9%e6%89%98%e7%ae%a1%e7%9a%84%e9%80%89%e6%8b%a9">第三方托管的选择</a> </li> <li> 4.10 <a href="/book/zh/v2/%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e7%9a%84-Git-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>5. <a href="/book/zh/v2/%e5%88%86%e5%b8%83%e5%bc%8f-Git-%e5%88%86%e5%b8%83%e5%bc%8f%e5%b7%a5%e4%bd%9c%e6%b5%81%e7%a8%8b">分布式 Git</a></h2> <ol> <li> 5.1 <a href="/book/zh/v2/%e5%88%86%e5%b8%83%e5%bc%8f-Git-%e5%88%86%e5%b8%83%e5%bc%8f%e5%b7%a5%e4%bd%9c%e6%b5%81%e7%a8%8b">分布式工作流程</a> </li> <li> 5.2 <a href="/book/zh/v2/%e5%88%86%e5%b8%83%e5%bc%8f-Git-%e5%90%91%e4%b8%80%e4%b8%aa%e9%a1%b9%e7%9b%ae%e8%b4%a1%e7%8c%ae">向一个项目贡献</a> </li> <li> 5.3 <a href="/book/zh/v2/%e5%88%86%e5%b8%83%e5%bc%8f-Git-%e7%bb%b4%e6%8a%a4%e9%a1%b9%e7%9b%ae">维护项目</a> </li> <li> 5.4 <a href="/book/zh/v2/%e5%88%86%e5%b8%83%e5%bc%8f-Git-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> </ol> </div> <div class='column-middle'> <ol class='book-toc'> <li class='chapter'> <h2>6. <a href="/book/zh/v2/GitHub-%e8%b4%a6%e6%88%b7%e7%9a%84%e5%88%9b%e5%bb%ba%e5%92%8c%e9%85%8d%e7%bd%ae">GitHub</a></h2> <ol> <li> 6.1 <a href="/book/zh/v2/GitHub-%e8%b4%a6%e6%88%b7%e7%9a%84%e5%88%9b%e5%bb%ba%e5%92%8c%e9%85%8d%e7%bd%ae">账户的创建和配置</a> </li> <li> 6.2 <a href="/book/zh/v2/GitHub-%e5%af%b9%e9%a1%b9%e7%9b%ae%e5%81%9a%e5%87%ba%e8%b4%a1%e7%8c%ae">对项目做出贡献</a> </li> <li> 6.3 <a href="/book/zh/v2/GitHub-%e7%bb%b4%e6%8a%a4%e9%a1%b9%e7%9b%ae">维护项目</a> </li> <li> 6.4 <a href="/book/zh/v2/GitHub-%e7%ae%a1%e7%90%86%e7%bb%84%e7%bb%87">管理组织</a> </li> <li> 6.5 <a href="/book/zh/v2/GitHub-%e8%84%9a%e6%9c%ac-GitHub">脚本 GitHub</a> </li> <li> 6.6 <a href="/book/zh/v2/GitHub-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>7. <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e9%80%89%e6%8b%a9%e4%bf%ae%e8%ae%a2%e7%89%88%e6%9c%ac">Git 工具</a></h2> <ol> <li> 7.1 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e9%80%89%e6%8b%a9%e4%bf%ae%e8%ae%a2%e7%89%88%e6%9c%ac">选择修订版本</a> </li> <li> 7.2 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e4%ba%a4%e4%ba%92%e5%bc%8f%e6%9a%82%e5%ad%98">交互式暂存</a> </li> <li> 7.3 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e8%b4%ae%e8%97%8f%e4%b8%8e%e6%b8%85%e7%90%86">贮藏与清理</a> </li> <li> 7.4 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e7%ad%be%e7%bd%b2%e5%b7%a5%e4%bd%9c">签署工作</a> </li> <li> 7.5 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e6%90%9c%e7%b4%a2">搜索</a> </li> <li> 7.6 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e9%87%8d%e5%86%99%e5%8e%86%e5%8f%b2">重写历史</a> </li> <li> 7.7 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e9%87%8d%e7%bd%ae%e6%8f%ad%e5%af%86">重置揭密</a> </li> <li> 7.8 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e9%ab%98%e7%ba%a7%e5%90%88%e5%b9%b6">高级合并</a> </li> <li> 7.9 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-Rerere">Rerere</a> </li> <li> 7.10 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e4%bd%bf%e7%94%a8-Git-%e8%b0%83%e8%af%95">使用 Git 调试</a> </li> <li> 7.11 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e5%ad%90%e6%a8%a1%e5%9d%97">子模块</a> </li> <li> 7.12 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e6%89%93%e5%8c%85">打包</a> </li> <li> 7.13 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e6%9b%bf%e6%8d%a2">替换</a> </li> <li> 7.14 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e5%87%ad%e8%af%81%e5%ad%98%e5%82%a8">凭证存储</a> </li> <li> 7.15 <a href="/book/zh/v2/Git-%e5%b7%a5%e5%85%b7-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>8. <a href="/book/zh/v2/%e8%87%aa%e5%ae%9a%e4%b9%89-Git-%e9%85%8d%e7%bd%ae-Git">自定义 Git</a></h2> <ol> <li> 8.1 <a href="/book/zh/v2/%e8%87%aa%e5%ae%9a%e4%b9%89-Git-%e9%85%8d%e7%bd%ae-Git">配置 Git</a> </li> <li> 8.2 <a href="/book/zh/v2/%e8%87%aa%e5%ae%9a%e4%b9%89-Git-Git-%e5%b1%9e%e6%80%a7">Git 属性</a> </li> <li> 8.3 <a href="/book/zh/v2/%e8%87%aa%e5%ae%9a%e4%b9%89-Git-Git-%e9%92%a9%e5%ad%90">Git 钩子</a> </li> <li> 8.4 <a href="/book/zh/v2/%e8%87%aa%e5%ae%9a%e4%b9%89-Git-%e4%bd%bf%e7%94%a8%e5%bc%ba%e5%88%b6%e7%ad%96%e7%95%a5%e7%9a%84%e4%b8%80%e4%b8%aa%e4%be%8b%e5%ad%90">使用强制策略的一个例子</a> </li> <li> 8.5 <a href="/book/zh/v2/%e8%87%aa%e5%ae%9a%e4%b9%89-Git-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>9. <a href="/book/zh/v2/Git-%e4%b8%8e%e5%85%b6%e4%bb%96%e7%b3%bb%e7%bb%9f-%e4%bd%9c%e4%b8%ba%e5%ae%a2%e6%88%b7%e7%ab%af%e7%9a%84-Git">Git 与其他系统</a></h2> <ol> <li> 9.1 <a href="/book/zh/v2/Git-%e4%b8%8e%e5%85%b6%e4%bb%96%e7%b3%bb%e7%bb%9f-%e4%bd%9c%e4%b8%ba%e5%ae%a2%e6%88%b7%e7%ab%af%e7%9a%84-Git">作为客户端的 Git</a> </li> <li> 9.2 <a href="/book/zh/v2/Git-%e4%b8%8e%e5%85%b6%e4%bb%96%e7%b3%bb%e7%bb%9f-%e8%bf%81%e7%a7%bb%e5%88%b0-Git">迁移到 Git</a> </li> <li> 9.3 <a href="/book/zh/v2/Git-%e4%b8%8e%e5%85%b6%e4%bb%96%e7%b3%bb%e7%bb%9f-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>10. <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-%e5%ba%95%e5%b1%82%e5%91%bd%e4%bb%a4%e4%b8%8e%e4%b8%8a%e5%b1%82%e5%91%bd%e4%bb%a4">Git 内部原理</a></h2> <ol> <li> 10.1 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-%e5%ba%95%e5%b1%82%e5%91%bd%e4%bb%a4%e4%b8%8e%e4%b8%8a%e5%b1%82%e5%91%bd%e4%bb%a4">底层命令与上层命令</a> </li> <li> 10.2 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-Git-%e5%af%b9%e8%b1%a1">Git 对象</a> </li> <li> 10.3 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-Git-%e5%bc%95%e7%94%a8">Git 引用</a> </li> <li> 10.4 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-%e5%8c%85%e6%96%87%e4%bb%b6">包文件</a> </li> <li> 10.5 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-%e5%bc%95%e7%94%a8%e8%a7%84%e8%8c%83">引用规范</a> </li> <li> 10.6 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-%e4%bc%a0%e8%be%93%e5%8d%8f%e8%ae%ae">传输协议</a> </li> <li> 10.7 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-%e7%bb%b4%e6%8a%a4%e4%b8%8e%e6%95%b0%e6%8d%ae%e6%81%a2%e5%a4%8d">维护与数据恢复</a> </li> <li> 10.8 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f">环境变量</a> </li> <li> 10.9 <a href="/book/zh/v2/Git-%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> </ol> </div> <div class='column-right'> <ol class='book-toc'> <li class='chapter'> <h2>A1. <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-%e5%9b%be%e5%bd%a2%e7%95%8c%e9%9d%a2">附录 A: 在其它环境中使用 Git</a></h2> <ol> <li> A1.1 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-%e5%9b%be%e5%bd%a2%e7%95%8c%e9%9d%a2">图形界面</a> </li> <li> A1.2 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-Visual-Studio-%e4%b8%ad%e7%9a%84-Git">Visual Studio 中的 Git</a> </li> <li> A1.3 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-Visual-Studio-Code-%e4%b8%ad%e7%9a%84-Git">Visual Studio Code 中的 Git</a> </li> <li> A1.4 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-IntelliJ-/-PyCharm-/-WebStorm-/-PhpStorm-/-RubyMine-%e4%b8%ad%e7%9a%84-Git">IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git</a> </li> <li> A1.5 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-Sublime-Text-%e4%b8%ad%e7%9a%84-Git">Sublime Text 中的 Git</a> </li> <li> A1.6 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-Bash-%e4%b8%ad%e7%9a%84-Git">Bash 中的 Git</a> </li> <li> A1.7 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-Zsh-%e4%b8%ad%e7%9a%84-Git">Zsh 中的 Git</a> </li> <li> A1.8 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-Git-%e5%9c%a8-PowerShell-%e4%b8%ad%e4%bd%bf%e7%94%a8-Git">Git 在 PowerShell 中使用 Git</a> </li> <li> A1.9 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-A:-%e5%9c%a8%e5%85%b6%e5%ae%83%e7%8e%af%e5%a2%83%e4%b8%ad%e4%bd%bf%e7%94%a8-Git-%e6%80%bb%e7%bb%93">总结</a> </li> </ol> </li> <li class='chapter'> <h2>A2. <a href="/book/zh/v2/%e9%99%84%e5%bd%95-B:-%e5%9c%a8%e4%bd%a0%e7%9a%84%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%85%a5-Git-%e5%91%bd%e4%bb%a4%e8%a1%8c-Git-%e6%96%b9%e5%bc%8f">附录 B: 在你的应用中嵌入 Git</a></h2> <ol> <li> A2.1 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-B:-%e5%9c%a8%e4%bd%a0%e7%9a%84%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%85%a5-Git-%e5%91%bd%e4%bb%a4%e8%a1%8c-Git-%e6%96%b9%e5%bc%8f">命令行 Git 方式</a> </li> <li> A2.2 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-B:-%e5%9c%a8%e4%bd%a0%e7%9a%84%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%85%a5-Git-Libgit2">Libgit2</a> </li> <li> A2.3 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-B:-%e5%9c%a8%e4%bd%a0%e7%9a%84%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%85%a5-Git-JGit">JGit</a> </li> <li> A2.4 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-B:-%e5%9c%a8%e4%bd%a0%e7%9a%84%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%85%a5-Git-go-git">go-git</a> </li> <li> A2.5 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-B:-%e5%9c%a8%e4%bd%a0%e7%9a%84%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%85%a5-Git-Dulwich">Dulwich</a> </li> </ol> </li> <li class='chapter'> <h2>A3. <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e8%ae%be%e7%bd%ae%e4%b8%8e%e9%85%8d%e7%bd%ae">附录 C: Git 命令</a></h2> <ol> <li> A3.1 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e8%ae%be%e7%bd%ae%e4%b8%8e%e9%85%8d%e7%bd%ae">设置与配置</a> </li> <li> A3.2 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e8%8e%b7%e5%8f%96%e4%b8%8e%e5%88%9b%e5%bb%ba%e9%a1%b9%e7%9b%ae">获取与创建项目</a> </li> <li> A3.3 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e5%bf%ab%e7%85%a7%e5%9f%ba%e7%a1%80">快照基础</a> </li> <li> A3.4 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e5%88%86%e6%94%af%e4%b8%8e%e5%90%88%e5%b9%b6">分支与合并</a> </li> <li> A3.5 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e9%a1%b9%e7%9b%ae%e5%88%86%e4%ba%ab%e4%b8%8e%e6%9b%b4%e6%96%b0">项目分享与更新</a> </li> <li> A3.6 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e6%a3%80%e6%9f%a5%e4%b8%8e%e6%af%94%e8%be%83">检查与比较</a> </li> <li> A3.7 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e8%b0%83%e8%af%95">调试</a> </li> <li> A3.8 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e8%a1%a5%e4%b8%81">补丁</a> </li> <li> A3.9 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e9%82%ae%e4%bb%b6">邮件</a> </li> <li> A3.10 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e5%a4%96%e9%83%a8%e7%b3%bb%e7%bb%9f">外部系统</a> </li> <li> A3.11 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e7%ae%a1%e7%90%86">管理</a> </li> <li> A3.12 <a href="/book/zh/v2/%e9%99%84%e5%bd%95-C:-Git-%e5%91%bd%e4%bb%a4-%e5%ba%95%e5%b1%82%e5%91%bd%e4%bb%a4">底层命令</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>2.2 Git 基础 - 记录每次更新到仓库</h1> <div> <h2 id="_记录每次更新到仓库">记录每次更新到仓库</h2> <div class="paragraph"> <p>现在我们的机器上有了一个 <strong>真实项目</strong> 的 Git 仓库,并从这个仓库中检出了所有文件的 <strong>工作副本</strong>。 通常,你会对这些文件做些修改,每当完成了一个阶段的目标,想要将记录下它时,就将它提交到仓库。</p> </div> <div class="paragraph"> <p>请记住,你工作目录下的每一个文件都不外乎这两种状态:<strong>已跟踪</strong> 或 <strong>未跟踪</strong>。 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后, 它们的状态可能是未修改,已修改或已放入暂存区。简而言之,已跟踪的文件就是 Git 已经知道的文件。</p> </div> <div class="paragraph"> <p>工作目录中除已跟踪文件外的其它所有文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有被放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态,因为 Git 刚刚检出了它们, 而你尚未编辑过它们。</p> </div> <div class="paragraph"> <p>编辑过某些文件之后,由于自上次提交后你对它们做了修改,Git 将它们标记为已修改文件。 在工作时,你可以选择性地将这些修改过的文件放入暂存区,然后提交所有已暂存的修改,如此反复。</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/zh/v2/images/lifecycle.png" alt="Git 下文件生命周期图。"> </div> <div class="title">Figure 8. 文件的状态变化周期</div> </div> <div class="sect3"> <h3 id="_checking_status">检查当前文件状态</h3> <div class="paragraph"> <p>可以用 <code>git status</code> 命令查看哪些文件处于什么状态。 如果在克隆仓库后立即使用此命令,会看到类似这样的输出:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean</code></pre> </div> </div> <div class="paragraph"> <p>这说明你现在的工作目录相当干净。换句话说,所有已跟踪文件在上次提交后都未被更改过。 此外,上面的信息还表明,当前目录下没有出现任何处于未跟踪状态的新文件,否则 Git 会在这里列出来。 最后,该命令还显示了当前所在分支,并告诉你这个分支同远程服务器上对应的分支没有偏离。 现在,分支名是“master”,这是默认的分支名。 我们在 <a href="/book/zh/v2/ch00/ch03-git-branching">Git 分支</a> 中会详细讨论分支和引用。</p> </div> <div class="paragraph"> <p>现在,让我们在项目下创建一个新的 <code>README</code> 文件。 如果之前并不存在这个文件,使用 <code>git status</code> 命令,你将看到一个新的未跟踪文件:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ echo 'My Project' > README $ git status On branch master Your branch is up-to-date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)</code></pre> </div> </div> <div class="paragraph"> <p>在状态报告中可以看到新建的 <code>README</code> 文件出现在 <code>Untracked files</code> 下面。 未跟踪的文件意味着 Git 在之前的快照(提交)中没有这些文件;Git 不会自动将之纳入跟踪范围,除非你明明白白地告诉它“我需要跟踪该文件”。 这样的处理让你不必担心将生成的二进制文件或其它不想被跟踪的文件包含进来。 不过现在的例子中,我们确实想要跟踪管理 <code>README</code> 这个文件。</p> </div> </div> <div class="sect3"> <h3 id="_tracking_files">跟踪新文件</h3> <div class="paragraph"> <p>使用命令 <code>git add</code> 开始跟踪一个文件。 所以,要跟踪 <code>README</code> 文件,运行:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git add README</code></pre> </div> </div> <div class="paragraph"> <p>此时再运行 <code>git status</code> 命令,会看到 <code>README</code> 文件已被跟踪,并处于暂存状态:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: README</code></pre> </div> </div> <div class="paragraph"> <p>只要在 <code>Changes to be committed</code> 这行下面的,就说明是已暂存状态。 如果此时提交,那么该文件在你运行 <code>git add</code> 时的版本将被留存在后续的历史记录中。 你可能会想起之前我们使用 <code>git init</code> 后就运行了 <code>git add <files></code> 命令,开始跟踪当前目录下的文件。 <code>git add</code> 命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。</p> </div> </div> <div class="sect3"> <h3 id="_暂存已修改的文件">暂存已修改的文件</h3> <div class="paragraph"> <p>现在我们来修改一个已被跟踪的文件。 如果你修改了一个名为 <code>CONTRIBUTING.md</code> 的已被跟踪的文件,然后运行 <code>git status</code> 命令,会看到下面内容:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md</code></pre> </div> </div> <div class="paragraph"> <p>文件 <code>CONTRIBUTING.md</code> 出现在 <code>Changes not staged for commit</code> 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。 要暂存这次更新,需要运行 <code>git add</code> 命令。 这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。 将这个命令理解为“精确地将内容添加到下一次提交中”而不是“将一个文件添加到项目中”要更加合适。 现在让我们运行 <code>git add</code> 将“CONTRIBUTING.md”放到暂存区,然后再看看 <code>git status</code> 的输出:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git add CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README modified: CONTRIBUTING.md</code></pre> </div> </div> <div class="paragraph"> <p>现在两个文件都已暂存,下次提交时就会一并记录到仓库。 假设此时,你想要在 <code>CONTRIBUTING.md</code> 里再加条注释。 重新编辑存盘后,准备好提交。 不过且慢,再运行 <code>git status</code> 看看:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ vim CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README modified: CONTRIBUTING.md Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md</code></pre> </div> </div> <div class="paragraph"> <p>怎么回事? 现在 <code>CONTRIBUTING.md</code> 文件同时出现在暂存区和非暂存区。 这怎么可能呢? 好吧,实际上 Git 只不过暂存了你运行 <code>git add</code> 命令时的版本。 如果你现在提交,<code>CONTRIBUTING.md</code> 的版本是你最后一次运行 <code>git add</code> 命令时的那个版本,而不是你运行 <code>git commit</code> 时,在工作目录中的当前版本。 所以,运行了 <code>git add</code> 之后又作了修订的文件,需要重新运行 <code>git add</code> 把最新版本重新暂存起来:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git add CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README modified: CONTRIBUTING.md</code></pre> </div> </div> </div> <div class="sect3"> <h3 id="_状态简览">状态简览</h3> <div class="paragraph"> <p><code>git status</code> 命令的输出十分详细,但其用语有些繁琐。 Git 有一个选项可以帮你缩短状态命令的输出,这样可以以简洁的方式查看更改。 如果你使用 <code>git status -s</code> 命令或 <code>git status --short</code> 命令,你将得到一种格式更为紧凑的输出。</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git status -s M README MM Rakefile A lib/git.rb M lib/simplegit.rb ?? LICENSE.txt</code></pre> </div> </div> <div class="paragraph"> <p>新添加的未跟踪文件前面有 <code>??</code> 标记,新添加到暂存区中的文件前面有 <code>A</code> 标记,修改过的文件前面有 <code>M</code> 标记。 输出中有两栏,左栏指明了暂存区的状态,右栏指明了工作区的状态。例如,上面的状态报告显示: <code>README</code> 文件在工作区已修改但尚未暂存,而 <code>lib/simplegit.rb</code> 文件已修改且已暂存。 <code>Rakefile</code> 文件已修改,暂存后又作了修改,因此该文件的修改中既有已暂存的部分,又有未暂存的部分。</p> </div> </div> <div class="sect3"> <h3 id="_ignoring">忽略文件</h3> <div class="paragraph"> <p>一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 <code>.gitignore</code> 的文件,列出要忽略的文件的模式。 来看一个实际的 <code>.gitignore</code> 例子:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ cat .gitignore *.[oa] *~</code></pre> </div> </div> <div class="paragraph"> <p>第一行告诉 Git 忽略所有以 <code>.o</code> 或 <code>.a</code> 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。 第二行告诉 Git 忽略所有名字以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。 此外,你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。 要养成一开始就为你的新仓库设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。</p> </div> <div class="paragraph"> <p>文件 <code>.gitignore</code> 的格式规范如下:</p> </div> <div class="ulist"> <ul> <li> <p>所有空行或者以 <code>#</code> 开头的行都会被 Git 忽略。</p> </li> <li> <p>可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。</p> </li> <li> <p>匹配模式可以以(<code>/</code>)开头防止递归。</p> </li> <li> <p>匹配模式可以以(<code>/</code>)结尾指定目录。</p> </li> <li> <p>要忽略指定模式以外的文件或目录,可以在模式前加上叹号(<code>!</code>)取反。</p> </li> </ul> </div> <div class="paragraph"> <p>所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(<code>*</code>)匹配零个或多个任意字符;<code>[abc]</code> 匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c); 问号(<code>?</code>)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 <code>[0-9]</code> 表示匹配所有 0 到 9 的数字)。 使用两个星号(<code>**</code>)表示匹配任意中间目录,比如 <code>a/**/z</code> 可以匹配 <code>a/z</code> 、 <code>a/b/z</code> 或 <code>a/b/c/z</code> 等。</p> </div> <div class="paragraph"> <p>我们再看一个 <code>.gitignore</code> 文件的例子:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code># 忽略所有的 .a 文件 *.a # 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件 !lib.a # 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO /TODO # 忽略任何目录下名为 build 的文件夹 build/ # 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt doc/*.txt # 忽略 doc/ 目录及其所有子目录下的 .pdf 文件 doc/**/*.pdf</code></pre> </div> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <div class="title">Tip</div> </td> <td class="content"> <div class="paragraph"> <p>GitHub 有一个十分详细的针对数十种项目及语言的 <code>.gitignore</code> 文件列表, 你可以在 <a href="https://github.com/github/gitignore" class="bare">https://github.com/github/gitignore</a> 找到它。</p> </div> </td> </tr> </table> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content"> <div class="paragraph"> <p>在最简单的情况下,一个仓库可能只根目录下有一个 <code>.gitignore</code> 文件,它递归地应用到整个仓库中。 然而,子目录下也可以有额外的 <code>.gitignore</code> 文件。子目录中的 <code>.gitignore</code> 文件中的规则只作用于它所在的目录中。 (Linux 内核的源码库拥有 206 个 <code>.gitignore</code> 文件。)</p> </div> <div class="paragraph"> <p>多个 <code>.gitignore</code> 文件的具体细节超出了本书的范围,更多详情见 <code>man gitignore</code> 。</p> </div> </td> </tr> </table> </div> </div> <div class="sect3"> <h3 id="_git_diff_staged">查看已暂存和未暂存的修改</h3> <div class="paragraph"> <p>如果 <code>git status</code> 命令的输出对于你来说过于简略,而你想知道具体修改了什么地方,可以用 <code>git diff</code> 命令。 稍后我们会详细介绍 <code>git diff</code>,你通常可能会用它来回答这两个问题:当前做的哪些更新尚未暂存? 有哪些更新已暂存并准备好下次提交? 虽然 <code>git status</code> 已经通过在相应栏下列出文件名的方式回答了这个问题,但 <code>git diff</code> 能通过文件补丁的格式更加具体地显示哪些行发生了改变。</p> </div> <div class="paragraph"> <p>假如再次修改 README 文件后暂存,然后编辑 <code>CONTRIBUTING.md</code> 文件后先不暂存, 运行 <code>status</code> 命令将会看到:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: README Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md</code></pre> </div> </div> <div class="paragraph"> <p>要查看尚未暂存的文件更新了哪些部分,不加参数直接输入 <code>git diff</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git diff diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ebb991..643e24f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,8 @@ branch directly, things can get messy. Please include a nice description of your changes when you submit your PR; if we have to read the whole diff to figure out why you're contributing in the first place, you're less likely to get feedback and have your change -merged in. +merged in. Also, split your changes into comprehensive chunks if your patch is +longer than a dozen lines. If you are starting to work on a particular area, feel free to submit a PR that highlights your work in progress (and note in the PR title that it's</code></pre> </div> </div> <div class="paragraph"> <p>此命令比较的是工作目录中当前文件和暂存区域快照之间的差异。 也就是修改之后还没有暂存起来的变化内容。</p> </div> <div class="paragraph"> <p>若要查看已暂存的将要添加到下次提交里的内容,可以用 <code>git diff --staged</code> 命令。 这条命令将比对已暂存文件与最后一次提交的文件差异:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git diff --staged diff --git a/README b/README new file mode 100644 index 0000000..03902a1 --- /dev/null +++ b/README @@ -0,0 +1 @@ +My Project</code></pre> </div> </div> <div class="paragraph"> <p>请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件,运行 <code>git diff</code> 后却什么也没有,就是这个原因。</p> </div> <div class="paragraph"> <p>像之前说的,暂存 <code>CONTRIBUTING.md</code> 后再编辑,可以使用 <code>git status</code> 查看已被暂存的修改或未被暂存的修改。 如果我们的环境(终端输出)看起来如下:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git add CONTRIBUTING.md $ echo '# test line' >> CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: CONTRIBUTING.md Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md</code></pre> </div> </div> <div class="paragraph"> <p>现在运行 <code>git diff</code> 看暂存前后的变化:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git diff diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 643e24f..87f08c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,3 +119,4 @@ at the ## Starter Projects See our [projects list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md). +# test line</code></pre> </div> </div> <div class="paragraph"> <p>然后用 <code>git diff --cached</code> 查看已经暂存起来的变化( <code>--staged</code> 和 <code>--cached</code> 是同义词):</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git diff --cached diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ebb991..643e24f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,8 @@ branch directly, things can get messy. Please include a nice description of your changes when you submit your PR; if we have to read the whole diff to figure out why you're contributing in the first place, you're less likely to get feedback and have your change -merged in. +merged in. Also, split your changes into comprehensive chunks if your patch is +longer than a dozen lines. If you are starting to work on a particular area, feel free to submit a PR that highlights your work in progress (and note in the PR title that it's</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content"> <div class="title">Git Diff 的插件版本</div> <div class="paragraph"> <p>在本书中,我们使用 <code>git diff</code> 来分析文件差异。 但是你也可以使用图形化的工具或外部 diff 工具来比较差异。 可以使用 <code>git difftool</code> 命令来调用 emerge 或 vimdiff 等软件(包括商业软件)输出 diff 的分析结果。 使用 <code>git difftool --tool-help</code> 命令来看你的系统支持哪些 Git Diff 插件。</p> </div> </td> </tr> </table> </div> </div> <div class="sect3"> <h3 id="_committing_changes">提交更新</h3> <div class="paragraph"> <p>现在的暂存区已经准备就绪,可以提交了。 在此之前,请务必确认还有什么已修改或新建的文件还没有 <code>git add</code> 过, 否则提交的时候不会记录这些尚未暂存的变化。 这些已修改但未暂存的文件只会保留在本地磁盘。 所以,每次准备提交前,先用 <code>git status</code> 看下,你所需要的文件是不是都已暂存起来了, 然后再运行提交命令 <code>git commit</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git commit</code></pre> </div> </div> <div class="paragraph"> <p>这样会启动你选择的文本编辑器来输入提交说明。</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content"> <div class="paragraph"> <p>启动的编辑器是通过 Shell 的环境变量 <code>EDITOR</code> 指定的,一般为 vim 或 emacs。 当然也可以按照 <a href="/book/zh/v2/ch00/ch01-getting-started">起步</a> 介绍的方式, 使用 <code>git config --global core.editor</code> 命令设置你喜欢的编辑器。 </p> </div> </td> </tr> </table> </div> <div class="paragraph"> <p>编辑器会显示类似下面的文本信息(本例选用 Vim 的屏显方式展示):</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code># Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Your branch is up-to-date with 'origin/master'. # # Changes to be committed: # new file: README # modified: CONTRIBUTING.md # ~ ~ ~ ".git/COMMIT_EDITMSG" 9L, 283C</code></pre> </div> </div> <div class="paragraph"> <p>可以看到,默认的提交消息包含最后一次运行 <code>git status</code> 的输出,放在注释行里,另外开头还有一个空行,供你输入提交说明。 你完全可以去掉这些注释行,不过留着也没关系,多少能帮你回想起这次更新的内容有哪些。</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content"> <div class="paragraph"> <p>更详细的内容修改提示可以用 <code>-v</code> 选项查看,这会将你所作的更改的 diff 输出呈现在编辑器中,以便让你知道本次提交具体作出哪些修改。</p> </div> </td> </tr> </table> </div> <div class="paragraph"> <p>退出编辑器时,Git 会丢弃注释行,用你输入的提交说明生成一次提交。</p> </div> <div class="paragraph"> <p>另外,你也可以在 <code>commit</code> 命令后添加 <code>-m</code> 选项,将提交信息与命令放在同一行,如下所示:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git commit -m "Story 182: Fix benchmarks for speed" [master 463dc4f] Story 182: Fix benchmarks for speed 2 files changed, 2 insertions(+) create mode 100644 README</code></pre> </div> </div> <div class="paragraph"> <p>好,现在你已经创建了第一个提交! 可以看到,提交后它会告诉你,当前是在哪个分支(<code>master</code>)提交的,本次提交的完整 SHA-1 校验和是什么(<code>463dc4f</code>),以及在本次提交中,有多少文件修订过,多少行添加和删改过。</p> </div> <div class="paragraph"> <p>请记住,提交时记录的是放在暂存区域的快照。 任何还未暂存文件的仍然保持已修改状态,可以在下次提交时纳入版本管理。 每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。</p> </div> </div> <div class="sect3"> <h3 id="_跳过使用暂存区域">跳过使用暂存区域</h3> <div class="paragraph"> <p> 尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 <code>git commit</code> 加上 <code>-a</code> 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 <code>git add</code> 步骤:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md no changes added to commit (use "git add" and/or "git commit -a") $ git commit -a -m 'added new benchmarks' [master 83e38c7] added new benchmarks 1 file changed, 5 insertions(+), 0 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>看到了吗?提交之前不再需要 <code>git add</code> 文件“CONTRIBUTING.md”了。 这是因为 <code>-a</code> 选项使本次提交包含了所有修改过的文件。 这很方便,但是要小心,有时这个选项会将不需要的文件添加到提交中。</p> </div> </div> <div class="sect3"> <h3 id="_removing_files">移除文件</h3> <div class="paragraph"> <p> 要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 <code>git rm</code> 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。</p> </div> <div class="paragraph"> <p>如果只是简单地从工作目录中手工删除文件,运行 <code>git status</code> 时就会在 “Changes not staged for commit” 部分(也就是 <em>未暂存清单</em>)看到:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ rm PROJECTS.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: PROJECTS.md no changes added to commit (use "git add" and/or "git commit -a")</code></pre> </div> </div> <div class="paragraph"> <p>然后再运行 <code>git rm</code> 记录此次移除文件的操作:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git rm PROJECTS.md rm 'PROJECTS.md' $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: PROJECTS.md</code></pre> </div> </div> <div class="paragraph"> <p>下一次提交时,该文件就不再纳入版本管理了。 如果要删除之前修改过或已经放到暂存区的文件,则必须使用强制删除选项 <code>-f</code>(译注:即 force 的首字母)。 这是一种安全特性,用于防止误删尚未添加到快照的数据,这样的数据不能被 Git 恢复。</p> </div> <div class="paragraph"> <p>另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,你想让文件保留在磁盘,但是并不想让 Git 继续跟踪。 当你忘记添加 <code>.gitignore</code> 文件,不小心把一个很大的日志文件或一堆 <code>.a</code> 这样的编译生成文件添加到暂存区时,这一做法尤其有用。 为达到这一目的,使用 <code>--cached</code> 选项:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git rm --cached README</code></pre> </div> </div> <div class="paragraph"> <p><code>git rm</code> 命令后面可以列出文件或者目录的名字,也可以使用 <code>glob</code> 模式。比如:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git rm log/\*.log</code></pre> </div> </div> <div class="paragraph"> <p>注意到星号 <code>*</code> 之前的反斜杠 <code>\</code>, 因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开。 此命令删除 <code>log/</code> 目录下扩展名为 <code>.log</code> 的所有文件。 类似的比如:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git rm \*~</code></pre> </div> </div> <div class="paragraph"> <p>该命令会删除所有名字以 <code>~</code> 结尾的文件。</p> </div> </div> <div class="sect3"> <h3 id="_git_mv">移动文件</h3> <div class="paragraph"> <p> 不像其它的 VCS 系统,Git 并不显式跟踪文件移动操作。 如果在 Git 中重命名了某个文件,仓库中存储的元数据并不会体现出这是一次改名操作。 不过 Git 非常聪明,它会推断出究竟发生了什么,至于具体是如何做到的,我们稍后再谈。</p> </div> <div class="paragraph"> <p>既然如此,当你看到 Git 的 <code>mv</code> 命令时一定会困惑不已。 要在 Git 中对文件改名,可以这么做:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git mv file_from file_to</code></pre> </div> </div> <div class="paragraph"> <p>它会恰如预期般正常工作。 实际上,即便此时查看状态信息,也会明白无误地看到关于重命名操作的说明:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git mv README.md README $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: README.md -> README</code></pre> </div> </div> <div class="paragraph"> <p>其实,运行 <code>git mv</code> 就相当于运行了下面三条命令:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ mv README.md README $ git rm README.md $ git add README</code></pre> </div> </div> <div class="paragraph"> <p>如此分开操作,Git 也会意识到这是一次重命名,所以不管何种方式结果都一样。 两者唯一的区别在于,<code>git mv</code> 是一条命令而非三条命令,直接使用 <code>git mv</code> 方便得多。 不过在使用其他工具重命名文件时,记得在提交前 <code>git rm</code> 删除旧文件名,再 <code>git add</code> 添加新文件名。</p> </div> </div> <div id="nav"><a href="/book/zh/v2/Git-基础-获取-Git-仓库">prev</a> | <a href="/book/zh/v2/Git-基础-查看提交历史">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>