CINXE.COM
Git - Bijdragen aan een project
<!DOCTYPE html> <html lang="nl"> <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 - Bijdragen aan een project</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/Distributed-Git-Contributing-to-a-Project">English</a>. </p> <p> Full translation available in <table> <tr><td><a href="/book/az/v2/Paylanm%c4%b1%c5%9f-Git-Layih%c9%99y%c9%99-T%c3%b6hf%c9%99-verm%c9%99k">azərbaycan dili</a>,</td></tr> <tr><td><a href="/book/bg/v2/Git-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b8-%d0%98%d0%bd%d1%82%d0%b5%d1%80%d0%b0%d0%ba%d1%82%d0%b8%d0%b2%d0%bd%d0%be-%d0%b8%d0%bd%d0%b4%d0%b5%d0%ba%d1%81%d0%b8%d1%80%d0%b0%d0%bd%d0%b5">български език</a>,</td></tr> <tr><td><a href="/book/de/v2/Verteiltes-Git-An-einem-Projekt-mitwirken">Deutsch</a>,</td></tr> <tr><td><a href="/book/es/v2/Git-en-entornos-distribuidos-Contribuyendo-a-un-Proyecto">Español</a>,</td></tr> <tr><td><a href="/book/fr/v2/Git-distribu%c3%a9-Contribution-%c3%a0-un-projet">Français</a>,</td></tr> <tr><td><a href="/book/gr">Ελληνικά</a>,</td></tr> <tr><td><a href="/book/ja/v2/Git-%e3%81%a7%e3%81%ae%e5%88%86%e6%95%a3%e4%bd%9c%e6%a5%ad-%e3%83%97%e3%83%ad%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e3%81%b8%e3%81%ae%e8%b2%a2%e7%8c%ae">日本語</a>,</td></tr> <tr><td><a href="/book/ko/v2/%eb%b6%84%ec%82%b0-%ed%99%98%ea%b2%bd%ec%97%90%ec%84%9c%ec%9d%98-Git-%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8%ec%97%90-%ea%b8%b0%ec%97%ac%ed%95%98%ea%b8%b0">한국어</a>,</td></tr> <tr><td><a href="/book/nl/v2/Gedistribueerd-Git-Bijdragen-aan-een-project">Nederlands</a>,</td></tr> <tr><td><a href="/book/ru/v2/%d0%a0%d0%b0%d1%81%d0%bf%d1%80%d0%b5%d0%b4%d0%b5%d0%bb%d1%91%d0%bd%d0%bd%d1%8b%d0%b9-Git-%d0%a3%d1%87%d0%b0%d1%81%d1%82%d0%b8%d0%b5-%d0%b2-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b5">Русский</a>,</td></tr> <tr><td><a href="/book/sl/v2/Porazdeljeni-Git-Prispevek-k-projektu">Slovenščina</a>,</td></tr> <tr><td><a href="/book/tl/v2/Distributed-Git-Contributing-to-a-Project">Tagalog</a>,</td></tr> <tr><td><a href="/book/uk/v2/%d0%a0%d0%be%d0%b7%d0%bf%d0%be%d0%b4%d1%96%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-Git-%d0%92%d0%bd%d0%b5%d1%81%d0%b5%d0%bd%d0%bd%d1%8f-%d0%b7%d0%bc%d1%96%d0%bd-%d0%b4%d0%be-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d1%83">Українська</a></td></tr> <tr><td><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>,</td></tr> </table> </p> <p> Partial translations available in <table> <tr><td><a href="/book/cs/v2/Distribuovan%c3%bd-Git-P%c5%99isp%c3%adv%c3%a1n%c3%ad-do-projektu">Čeština</a>,</td></tr> <tr><td><a href="/book/mk/v2/%d0%94%d0%b8%d1%81%d1%82%d1%80%d0%b8%d0%b1%d1%83%d0%b8%d1%80%d0%b0%d0%bd-Git-%d0%9f%d1%80%d0%b8%d0%b4%d0%be%d0%bd%d0%b5%d1%81-%d0%ba%d0%be%d0%bd-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82">Македонски</a>,</td></tr> <tr><td><a href="/book/pl/v2/Rozproszony-Git-Wgrywanie-zmian-do-projektu">Polski</a>,</td></tr> <tr><td><a href="/book/sr/v2/%d0%94%d0%b8%d1%81%d1%82%d1%80%d0%b8%d0%b1%d1%83%d0%b8%d1%80%d0%b0%d0%bd%d0%b8-%d0%93%d0%b8%d1%82-%d0%9a%d0%b0%d0%ba%d0%be-%d1%81%d0%b5-%d0%b4%d0%b0%d1%98%d0%b5-%d0%b4%d0%be%d0%bf%d1%80%d0%b8%d0%bd%d0%be%d1%81-%d0%bf%d1%80%d0%be%d1%98%d0%b5%d0%ba%d1%82%d1%83">Српски</a>,</td></tr> <tr><td><a href="/book/uz/v2/Distributed-Git-Contributing-to-a-Project">Ўзбекча</a>,</td></tr> <tr><td><a href="/book/zh-tw/v2/%e5%88%86%e6%95%a3%e5%bc%8f%e7%9a%84-Git-%e5%b0%8d%e5%b0%88%e6%a1%88%e9%80%b2%e8%a1%8c%e8%b2%a2%e7%8d%bb">繁體中文</a>,</td></tr> </table> </p> <p> Translations started for <table> <tr><td><a href="/book/be/v2/Distributed-Git-Contributing-to-a-Project">Беларуская</a>,</td></tr> <tr><td><a href="/book/fa/v2/%da%af%db%8c%d8%aa-%d8%aa%d9%88%d8%b2%db%8c%d8%b9%e2%80%8c%d8%b4%d8%af%d9%87-%d9%85%d8%b4%d8%a7%d8%b1%da%a9%d8%aa-%d8%af%d8%b1-%db%8c%da%a9-%d9%be%d8%b1%d9%88%da%98%d9%87" dir="rtl">فارسی</a>,</td></tr> <tr><td><a href="/book/id/v2/Distributed-Git-Contributing-to-a-Project">Indonesian</a>,</td></tr> <tr><td><a href="/book/it/v2/Distributed-Git-Contributing-to-a-Project">Italiano</a>,</td></tr> <tr><td><a href="/book/ms/v2/Distributed-Git-Contributing-to-a-Project">Bahasa Melayu</a>,</td></tr> <tr><td><a href="/book/pt-br/v2/Distributed-Git-Contribuindo-com-um-Projeto">Português (Brasil)</a>,</td></tr> <tr><td><a href="/book/pt-pt/v2/Git-Distribu%c3%addo-Contributing-to-a-Project">Português (Portugal)</a>,</td></tr> <tr><td><a href="/book/sv/v2/Distribuerade-Git-Medverka-i-ett-projekt">Svenska</a>,</td></tr> <tr><td><a href="/book/tr/v2/Da%c4%9f%c4%b1t%c4%b1k-Git-Projenin-Geli%c5%9fiminde-Rol-Almak">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-nl">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/nl/v2/Aan-de-slag-Over-versiebeheer">Aan de slag</a></h2> <ol> <li> 1.1 <a href="/book/nl/v2/Aan-de-slag-Over-versiebeheer">Over versiebeheer</a> </li> <li> 1.2 <a href="/book/nl/v2/Aan-de-slag-Een-kort-historisch-overzicht-van-Git">Een kort historisch overzicht van Git</a> </li> <li> 1.3 <a href="/book/nl/v2/Aan-de-slag-Wat-is-Git%3F">Wat is Git?</a> </li> <li> 1.4 <a href="/book/nl/v2/Aan-de-slag-De-commando-regel">De commando-regel</a> </li> <li> 1.5 <a href="/book/nl/v2/Aan-de-slag-Git-installeren">Git installeren</a> </li> <li> 1.6 <a href="/book/nl/v2/Aan-de-slag-Git-klaarmaken-voor-eerste-gebruik">Git klaarmaken voor eerste gebruik</a> </li> <li> 1.7 <a href="/book/nl/v2/Aan-de-slag-Hulp-krijgen">Hulp krijgen</a> </li> <li> 1.8 <a href="/book/nl/v2/Aan-de-slag-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>2. <a href="/book/nl/v2/Git-Basics-Een-Git-repository-verkrijgen">Git Basics</a></h2> <ol> <li> 2.1 <a href="/book/nl/v2/Git-Basics-Een-Git-repository-verkrijgen">Een Git repository verkrijgen</a> </li> <li> 2.2 <a href="/book/nl/v2/Git-Basics-Wijzigingen-aan-de-repository-vastleggen">Wijzigingen aan de repository vastleggen</a> </li> <li> 2.3 <a href="/book/nl/v2/Git-Basics-De-commit-geschiedenis-bekijken">De commit geschiedenis bekijken</a> </li> <li> 2.4 <a href="/book/nl/v2/Git-Basics-Dingen-ongedaan-maken">Dingen ongedaan maken</a> </li> <li> 2.5 <a href="/book/nl/v2/Git-Basics-Werken-met-remotes">Werken met remotes</a> </li> <li> 2.6 <a href="/book/nl/v2/Git-Basics-Taggen-Labelen">Taggen (Labelen)</a> </li> <li> 2.7 <a href="/book/nl/v2/Git-Basics-Git-aliassen">Git aliassen</a> </li> <li> 2.8 <a href="/book/nl/v2/Git-Basics-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>3. <a href="/book/nl/v2/Branchen-in-Git-Branches-in-vogelvlucht">Branchen in Git</a></h2> <ol> <li> 3.1 <a href="/book/nl/v2/Branchen-in-Git-Branches-in-vogelvlucht">Branches in vogelvlucht</a> </li> <li> 3.2 <a href="/book/nl/v2/Branchen-in-Git-Eenvoudig-branchen-en-mergen">Eenvoudig branchen en mergen</a> </li> <li> 3.3 <a href="/book/nl/v2/Branchen-in-Git-Branch-beheer">Branch-beheer</a> </li> <li> 3.4 <a href="/book/nl/v2/Branchen-in-Git-Branch-workflows">Branch workflows</a> </li> <li> 3.5 <a href="/book/nl/v2/Branchen-in-Git-Branches-op-afstand-Remote-branches">Branches op afstand (Remote branches)</a> </li> <li> 3.6 <a href="/book/nl/v2/Branchen-in-Git-Rebasen">Rebasen</a> </li> <li> 3.7 <a href="/book/nl/v2/Branchen-in-Git-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>4. <a href="/book/nl/v2/Git-op-de-server-De-protocollen">Git op de server</a></h2> <ol> <li> 4.1 <a href="/book/nl/v2/Git-op-de-server-De-protocollen">De protocollen</a> </li> <li> 4.2 <a href="/book/nl/v2/Git-op-de-server-Git-op-een-server-krijgen">Git op een server krijgen</a> </li> <li> 4.3 <a href="/book/nl/v2/Git-op-de-server-Je-publieke-SSH-sleutel-genereren">Je publieke SSH sleutel genereren</a> </li> <li> 4.4 <a href="/book/nl/v2/Git-op-de-server-De-server-opzetten">De server opzetten</a> </li> <li> 4.5 <a href="/book/nl/v2/Git-op-de-server-Git-Daemon">Git Daemon</a> </li> <li> 4.6 <a href="/book/nl/v2/Git-op-de-server-Slimme-HTTP">Slimme HTTP</a> </li> <li> 4.7 <a href="/book/nl/v2/Git-op-de-server-GitWeb">GitWeb</a> </li> <li> 4.8 <a href="/book/nl/v2/Git-op-de-server-GitLab">GitLab</a> </li> <li> 4.9 <a href="/book/nl/v2/Git-op-de-server-Hosting-oplossingen-van-derden">Hosting oplossingen van derden</a> </li> <li> 4.10 <a href="/book/nl/v2/Git-op-de-server-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>5. <a href="/book/nl/v2/Gedistribueerd-Git-Gedistribueerde-workflows">Gedistribueerd Git</a></h2> <ol> <li> 5.1 <a href="/book/nl/v2/Gedistribueerd-Git-Gedistribueerde-workflows">Gedistribueerde workflows</a> </li> <li> 5.2 <a href="/book/nl/v2/Gedistribueerd-Git-Bijdragen-aan-een-project" class="active">Bijdragen aan een project</a> </li> <li> 5.3 <a href="/book/nl/v2/Gedistribueerd-Git-Het-beheren-van-een-project">Het beheren van een project</a> </li> <li> 5.4 <a href="/book/nl/v2/Gedistribueerd-Git-Samenvatting">Samenvatting</a> </li> </ol> </li> </ol> </div> <div class='column-middle'> <ol class='book-toc'> <li class='chapter'> <h2>6. <a href="/book/nl/v2/GitHub-Account-setup-en-configuratie">GitHub</a></h2> <ol> <li> 6.1 <a href="/book/nl/v2/GitHub-Account-setup-en-configuratie">Account setup en configuratie</a> </li> <li> 6.2 <a href="/book/nl/v2/GitHub-Aan-een-project-bijdragen">Aan een project bijdragen</a> </li> <li> 6.3 <a href="/book/nl/v2/GitHub-Een-project-onderhouden">Een project onderhouden</a> </li> <li> 6.4 <a href="/book/nl/v2/GitHub-Een-organisatie-beheren">Een organisatie beheren</a> </li> <li> 6.5 <a href="/book/nl/v2/GitHub-GitHub-Scripten">GitHub Scripten</a> </li> <li> 6.6 <a href="/book/nl/v2/GitHub-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>7. <a href="/book/nl/v2/Git-Tools-Revisie-Selectie">Git Tools</a></h2> <ol> <li> 7.1 <a href="/book/nl/v2/Git-Tools-Revisie-Selectie">Revisie Selectie</a> </li> <li> 7.2 <a href="/book/nl/v2/Git-Tools-Interactief-stagen">Interactief stagen</a> </li> <li> 7.3 <a href="/book/nl/v2/Git-Tools-Stashen-en-opschonen">Stashen en opschonen</a> </li> <li> 7.4 <a href="/book/nl/v2/Git-Tools-Je-werk-tekenen">Je werk tekenen</a> </li> <li> 7.5 <a href="/book/nl/v2/Git-Tools-Zoeken">Zoeken</a> </li> <li> 7.6 <a href="/book/nl/v2/Git-Tools-Geschiedenis-herschrijven">Geschiedenis herschrijven</a> </li> <li> 7.7 <a href="/book/nl/v2/Git-Tools-Reset-ontrafeld">Reset ontrafeld</a> </li> <li> 7.8 <a href="/book/nl/v2/Git-Tools-Mergen-voor-gevorderden">Mergen voor gevorderden</a> </li> <li> 7.9 <a href="/book/nl/v2/Git-Tools-Rerere">Rerere</a> </li> <li> 7.10 <a href="/book/nl/v2/Git-Tools-Debuggen-met-Git">Debuggen met Git</a> </li> <li> 7.11 <a href="/book/nl/v2/Git-Tools-Submodules">Submodules</a> </li> <li> 7.12 <a href="/book/nl/v2/Git-Tools-Bundelen">Bundelen</a> </li> <li> 7.13 <a href="/book/nl/v2/Git-Tools-Vervangen">Vervangen</a> </li> <li> 7.14 <a href="/book/nl/v2/Git-Tools-Het-opslaan-van-inloggegevens">Het opslaan van inloggegevens</a> </li> <li> 7.15 <a href="/book/nl/v2/Git-Tools-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>8. <a href="/book/nl/v2/Git-aanpassen-Git-configuratie">Git aanpassen</a></h2> <ol> <li> 8.1 <a href="/book/nl/v2/Git-aanpassen-Git-configuratie">Git configuratie</a> </li> <li> 8.2 <a href="/book/nl/v2/Git-aanpassen-Git-attributen">Git attributen</a> </li> <li> 8.3 <a href="/book/nl/v2/Git-aanpassen-Git-Hooks">Git Hooks</a> </li> <li> 8.4 <a href="/book/nl/v2/Git-aanpassen-Een-voorbeeld-van-Git-afgedwongen-beleid">Een voorbeeld van Git-afgedwongen beleid</a> </li> <li> 8.5 <a href="/book/nl/v2/Git-aanpassen-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>9. <a href="/book/nl/v2/Git-en-andere-systemen-Git-als-een-client">Git en andere systemen</a></h2> <ol> <li> 9.1 <a href="/book/nl/v2/Git-en-andere-systemen-Git-als-een-client">Git als een client</a> </li> <li> 9.2 <a href="/book/nl/v2/Git-en-andere-systemen-Migreren-naar-Git">Migreren naar Git</a> </li> <li> 9.3 <a href="/book/nl/v2/Git-en-andere-systemen-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>10. <a href="/book/nl/v2/Git-Binnenwerk-Binnenwerk-en-koetswerk-plumbing-and-porcelain">Git Binnenwerk</a></h2> <ol> <li> 10.1 <a href="/book/nl/v2/Git-Binnenwerk-Binnenwerk-en-koetswerk-plumbing-and-porcelain">Binnenwerk en koetswerk (plumbing and porcelain)</a> </li> <li> 10.2 <a href="/book/nl/v2/Git-Binnenwerk-Git-objecten">Git objecten</a> </li> <li> 10.3 <a href="/book/nl/v2/Git-Binnenwerk-Git-Referenties">Git Referenties</a> </li> <li> 10.4 <a href="/book/nl/v2/Git-Binnenwerk-Packfiles">Packfiles</a> </li> <li> 10.5 <a href="/book/nl/v2/Git-Binnenwerk-De-Refspec">De Refspec</a> </li> <li> 10.6 <a href="/book/nl/v2/Git-Binnenwerk-Uitwisseling-protocollen">Uitwisseling protocollen</a> </li> <li> 10.7 <a href="/book/nl/v2/Git-Binnenwerk-Onderhoud-en-gegevensherstel">Onderhoud en gegevensherstel</a> </li> <li> 10.8 <a href="/book/nl/v2/Git-Binnenwerk-Omgevingsvariabelen">Omgevingsvariabelen</a> </li> <li> 10.9 <a href="/book/nl/v2/Git-Binnenwerk-Samenvatting">Samenvatting</a> </li> </ol> </li> </ol> </div> <div class='column-right'> <ol class='book-toc'> <li class='chapter'> <h2>A1. <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Grafische-interfaces">Bijlage A: Git in andere omgevingen</a></h2> <ol> <li> A1.1 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Grafische-interfaces">Grafische interfaces</a> </li> <li> A1.2 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Git-in-Visual-Studio">Git in Visual Studio</a> </li> <li> A1.3 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Git-in-Visual-Studio-Code">Git in Visual Studio Code</a> </li> <li> A1.4 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Git-in-Eclipse">Git in Eclipse</a> </li> <li> A1.5 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Git-in-Sublime-Text">Git in Sublime Text</a> </li> <li> A1.6 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Git-in-Bash">Git in Bash</a> </li> <li> A1.7 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Git-in-Zsh">Git in Zsh</a> </li> <li> A1.8 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Git-in-PowerShell">Git in PowerShell</a> </li> <li> A1.9 <a href="/book/nl/v2/Bijlage-A:-Git-in-andere-omgevingen-Samenvatting">Samenvatting</a> </li> </ol> </li> <li class='chapter'> <h2>A2. <a href="/book/nl/v2/Bijlage-B:-Git-in-je-applicaties-inbouwen-Commando-regel-Git">Bijlage B: Git in je applicaties inbouwen</a></h2> <ol> <li> A2.1 <a href="/book/nl/v2/Bijlage-B:-Git-in-je-applicaties-inbouwen-Commando-regel-Git">Commando-regel Git</a> </li> <li> A2.2 <a href="/book/nl/v2/Bijlage-B:-Git-in-je-applicaties-inbouwen-Libgit2">Libgit2</a> </li> <li> A2.3 <a href="/book/nl/v2/Bijlage-B:-Git-in-je-applicaties-inbouwen-JGit">JGit</a> </li> <li> A2.4 <a href="/book/nl/v2/Bijlage-B:-Git-in-je-applicaties-inbouwen-go-git">go-git</a> </li> <li> A2.5 <a href="/book/nl/v2/Bijlage-B:-Git-in-je-applicaties-inbouwen-Dulwich">Dulwich</a> </li> </ol> </li> <li class='chapter'> <h2>A3. <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Setup-en-configuratie">Bijlage C: Git Commando’s</a></h2> <ol> <li> A3.1 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Setup-en-configuratie">Setup en configuratie</a> </li> <li> A3.2 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Projecten-ophalen-en-maken">Projecten ophalen en maken</a> </li> <li> A3.3 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Basic-Snapshotten">Basic Snapshotten</a> </li> <li> A3.4 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Branchen-en-mergen">Branchen en mergen</a> </li> <li> A3.5 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Projecten-delen-en-bijwerken">Projecten delen en bijwerken</a> </li> <li> A3.6 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Inspectie-en-vergelijking">Inspectie en vergelijking</a> </li> <li> A3.7 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Debuggen">Debuggen</a> </li> <li> A3.8 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Patchen">Patchen</a> </li> <li> A3.9 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Email">Email</a> </li> <li> A3.10 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Externe-systemen">Externe systemen</a> </li> <li> A3.11 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Beheer">Beheer</a> </li> <li> A3.12 <a href="/book/nl/v2/Bijlage-C:-Git-Commando%e2%80%99s-Binnenwerk-commando%e2%80%99s-plumbing-commando%e2%80%99s">Binnenwerk commando’s (plumbing commando’s)</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>5.2 Gedistribueerd Git - Bijdragen aan een project</h1> <div> <h2 id="_contributing_project">Bijdragen aan een project</h2> <div class="paragraph"> <p> De grote moeilijkheid bij het beschrijven van dit proces is dat er een enorm aantal variaties mogelijk zijn in hoe het gebeurt. Om dat Git erg flexibel is, kunnen en zullen mensen op vele manieren samenwerken, en het is lastig om te beschrijven hoe je zou moeten bijdragen aan een project — ieder project is net weer een beetje anders. Een aantal van de betrokken variabelen zijn het aantal actieve bijdragers, gekozen workflow, je commit toegang, en mogelijk de manier waarop externe bijdragen worden gedaan.</p> </div> <div class="paragraph"> <p>De eerste variabele is het aantal actieve bijdragers. Hoeveel gebruikers dragen actief code bij aan dit project, en hoe vaak? In veel gevallen zal je twee of drie ontwikkelaars met een paar commits per dag hebben, of misschien minder voor wat meer slapende projecten. Voor zeer grote bedrijven of projecten kan het aantal ontwikkelaars in de duizenden lopen, met tientallen of zelfs honderden patches die iedere dag binnenkomen. Dit is belangrijk omdat met meer en meer ontwikkelaars, je meer en meer problemen tegenkomt bij het je verzekeren dat code netjes gepatched of eenvoudig gemerged kan worden. Wijzigingen die je indient kunnen verouderd of zwaar beschadigd raken door werk dat gemerged is terwijl je ermee aan het werken was, of terwijl je wijzigingen in de wacht stonden voor goedkeuring of toepassing. Hoe kun je jouw code consequent up-to-date en je patches geldig houden?</p> </div> <div class="paragraph"> <p>De volgende variabele is de gebruikte workflow in het project. Is het gecentraliseerd, waarbij iedere ontwikkelaar gelijkwaardige schrijftoegang heeft tot de hoofd codebasis? Heeft het project een eigenaar of integrator die alle patches controleert? Worden alle patches ge(peer)reviewed en goedgekeurd? Ben jij betrokken bij dat proces? Is er een luitenanten systeem neergezet, en moet je je werk eerst bij hen inleveren?</p> </div> <div class="paragraph"> <p>De volgende variabele is je commit toegang. De benodigde workflow om bij te dragen aan een project is heel anders als je schrijftoegang hebt tot het project dan wanneer je dat niet hebt. Als je geen schrijftoegang hebt, wat is de voorkeur van het project om bijdragen te ontvangen? Is er überhaupt een beleid? Hoeveel werk draag je per keer bij? Hoe vaak draag je bij?</p> </div> <div class="paragraph"> <p>Al deze vragen kunnen van invloed zijn op hoe je effectief bijdraagt aan een project en welke workflows de voorkeur hebben of beschikbaar zijn. We zullen een aantal van deze aspecten behandelen in een aantal voorbeelden, waarbij we van eenvoudig tot complexzullen gaan. Je zou in staat moeten zijn om de specifieke workflows die je in jouw praktijk nodig hebt te kunnen herleiden naar deze voorbeelden.</p> </div> <div class="sect3"> <h3 id="_commit_guidelines">Commit richtlijnen</h3> <div class="paragraph"> <p>Voordat we gaan kijken naar de specifieke gebruiksscenario’s, volgt hier een kort stukje over commit berichten. Het hebben van een goede richtlijn voor het maken commits en je daar aan houden maakt het werken met Git en samenwerken met anderen een stuk makkelijker. Het Git project levert een document waarin een aantal goede tips staan voor het maken van commits waaruit je patches kunt indienen — je kunt het lezen in de Git broncode in het <code>Documentation/SubmittingPatches</code> bestand.</p> </div> <div class="paragraph"> <p> Als eerste wil je geen witruimte-fouten indienen. Git geeft je een eenvoudige manier om hierop te controleren — voordat je commit, voer <code>git diff --check</code> uit, wat mogelijke witruimte-fouten identificeert en ze voor je afdrukt.</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/git-diff-check.png" alt="Uitvoer van `git diff --check`."> </div> <div class="title">Figuur 57. Uitvoer van <code>git diff --check</code>.</div> </div> <div class="paragraph"> <p>Als je dat commando uitvoert alvorens te committen, kun je al zien of je op het punt staat witruimte problemen te committen waaraan andere ontwikkelaars zich zouden kunnen ergeren.</p> </div> <div class="paragraph"> <p>Probeer vervolgens om van elke commit een logische set wijzigingen te maken. Probeer, als het je lukt, om je wijzigingen verteerbaar te houden — ga niet het hele weekend zitten coderen op vijf verschillende problemen om dat vervolgens op maandag als één gigantische commit in te dienen. Zelfs als je gedurende het weekend niet commit, gebruik dan het staging gebied op maandag om je werk in ten minste één commit per probleem op te splitsen, met een bruikbaar bericht per commit. Als een paar van de wijzigingen hetzelfde bestand betreffen, probeer dan <code>git add --patch</code> te gebruiken om bestanden gedeeltelijk te stagen (in detail behandeld in <a href="/book/nl/v2/ch00/_interactive_staging">Interactief stagen</a>). De snapshot aan de kop van het project is gelijk of je nu één commit doet of vijf, zolang alle wijzigingen op een gegeven moment maar toegevoegd zijn, probeer dus om het je mede-ontwikkelaars makkelijk te maken als ze je wijzigingen moeten beoordelen.</p> </div> <div class="paragraph"> <p>Deze aanpak maakt het ook makkelijker om één wijziging eruit te selecteren of terug te draaien, mocht dat later nodig zijn. <a href="/book/nl/v2/ch00/_rewriting_history">Geschiedenis herschrijven</a> beschrijft een aantal handige Git trucs om geschiedenis te herschrijven en bestanden interactief te stagen — gebruik deze instrumenten als hulp om een schone en begrijpelijke historie op te bouwen voordat deze naar iemand anders wordt gestuurd.</p> </div> <div class="paragraph"> <p>Het laatste om in gedachten te houden is het commit bericht. Als je er een gewoonte van maakt om commit berichten van goede kwaliteit aan te maken, dan maakt dat het gebruik van en samenwerken in Git een stuk eenvoudiger. In het algemeen zouden je berichten moeten beginnen met een enkele regel die niet langer is dan 50 karakters en die de wijzigingen beknopt omschrijft, gevolgd door een lege regel en daarna een meer gedetailleerde uitleg. Het Git project vereist dat de meer gedetailleerde omschrijving ook je motivatie voor de verandering bevat, en de nieuwe implementatie tegen het oude gedrag afzet — dit is een goede richtlijn om te volgen. Het is ook een goed idee om de gebiedende wijs te gebruiken in deze berichten. Met andere woorden, schrijf: "Los fout op" en niet "Fout opgelost" of "Dit lost fout op". Hier is een <a href="https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html">sjabloon dat origineel geschreven is door Tim Pope</a>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-text" data-lang="text">Capitalized, short (50 chars or less) summary More detailed explanatory text, if necessary. Wrap it to about 72 characters or so. In some contexts, the first line is treated as the subject of an email and the rest of the text as the body. The blank line separating the summary from the body is critical (unless you omit the body entirely); tools like rebase can get confused if you run the two together. Write your commit message in the imperative: "Fix bug" and not "Fixed bug" or "Fixes bug." This convention matches up with commit messages generated by commands like git merge and git revert. Further paragraphs come after blank lines. - Bullet points are okay, too - Typically a hyphen or asterisk is used for the bullet, followed by a single space, with blank lines in between, but conventions vary here - Use a hanging indent</code></pre> </div> </div> <div class="paragraph"> <p>Als al je commit berichten er zo uit zien, dan zullen de dingen een stuk eenvoudiger zijn voor jou en de ontwikkelaars waar je mee samenwerkt. Het Git project heeft goed geformatteerde commit berichten - ik raad je aan om <code>git log --no-merges</code> uit te voeren om te zien hoe een goed geformatteerde project-commit historie eruit ziet.</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Noot</div> </td> <td class="content"> <div class="title">Doe wat wij zeggen, niet wat wij doen.</div> <div class="paragraph"> <p>In de volgende voorbeelden en verder door de rest van dit boek, zijn omwille van bondigheid, de berichten niet zo netjes geformateerd als dit; in plaats daarvan gebruiken we de <code>-m</code> optie voor <code>git commit</code>.</p> </div> <div class="paragraph"> <p>Kortom: doe wat wij zeggen, niet wat wij doen.</p> </div> </td> </tr> </table> </div> </div> <div class="sect3"> <h3 id="_private_team">Besloten klein team</h3> <div class="paragraph"> <p> De eenvoudigste opzet die je waarschijnlijk zult tegenkomen is een besloten project met één of twee andere ontwikkelaars. Met “besloten” bedoel ik gesloten broncode — zonder leestoegang voor de buitenwereld. Jij en de andere ontwikkelaars hebben allemaal push toegang op de repository.</p> </div> <div class="paragraph"> <p>In deze omgeving kan je een workflow aanhouden die vergelijkbaar is met wat je zou doen als je Subversion of een andere gecentraliseerd systeem zou gebruiken. Je hebt nog steeds de voordelen van zaken als offline committen en veel eenvoudiger branchen en mergen, maar de workflow kan erg vergelijkbaar zijn. Het grootste verschil is dat het mergen aan de client-kant gebeurt en niet tijdens het committen aan de server-kant. Laten we eens kijken hoe het er uit zou kunnen zien als twee ontwikkelaars samen beginnen te werken met een gedeelde repository. De eerste ontwikkelaar, John, kloont de repository, maakt een wijziging, en commit lokaal. (De protocol berichten zijn met <code>...</code> vervangen in deze voorbeelden om ze iets in te korten.)</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># John's Machine $ git clone john@githost:simplegit.git Cloning into 'simplegit'... ... $ cd simplegit/ $ vim lib/simplegit.rb $ git commit -am 'remove invalid default value' [master 738ee87] remove invalid default value 1 files changed, 1 insertions(+), 1 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>De tweede ontwikkelaar, Jessica, doet hetzelfde — kloont de repository en commit een wijziging:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Jessica's Machine $ git clone jessica@githost:simplegit.git Cloning into 'simplegit'... ... $ cd simplegit/ $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Nu pusht Jessica haar werk naar de server, en dat werkt prima:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Jessica's Machine $ git push origin master ... To jessica@githost:simplegit.git 1edee6b..fbff5bc master -> master</code></pre> </div> </div> <div class="paragraph"> <p>De laatste regel van de uitvoer hierboven laat een bruikbaar bericht zien van de push-operatie. Het basis-formaat is <code><oldref>..<newref> fromref -> toref</code>, waar <code>oldref</code> de oude reference inhoudt, <code>newref</code> betekent de nieuwe referentie, <code>fromref</code> is de naam van de lokale referentie die gepusht wordt, en <code>toref</code> is de naam van de remote referentie die wordt geupdate. Je zult een vergelijkbare uitvoer zien in de behandeling hieronder, dus een basis inzicht hebben in de betekenins zal helpen met het begrijpen van de verschillende stadia van de repositories. Meer details zijn beschikbaar in de documentie van <a href="https://git-scm.com/docs/git-push">git-push</a>.</p> </div> <div class="paragraph"> <p>We gaan door met het voorbeeld, John maakt wat wijzigingen, commit deze naar zijn lokale repository en probeert ze naar dezelfde server te pushen:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># John's Machine $ git push origin master To john@githost:simplegit.git ! [rejected] master -> master (non-fast forward) error: failed to push some refs to 'john@githost:simplegit.git'</code></pre> </div> </div> <div class="paragraph"> <p>In dit geval zal de push van John falen, vanwege de eerdere push van Jessica met <em>haar</em> wijzigingen. Dit is belangrijk om te begrijpen als je gewend bent aan Subversion, omdat het je zal opvallen dat de twee ontwikkelaars niet hetzelfde bestand hebben aangepast. Waar Subversion automatisch zo’n merge op de server doet als verschillende bestanden zijn aangepast, moet je in Git de commits <em>eerst</em> lokaal mergen. Met andere wooren: John moet eerst Jessica’s wijzigingen ophalen en ze in zijn lokale repository mergen voor hij mag pushen:</p> </div> <div class="paragraph"> <p>Als eerste stap, gaat John Jessica’s werk eerst fetchen (dit zal alleen Jessica’s werk <em>fetchen</em>, het zal het nog niet in John’s werk mergen):</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git fetch origin ... From john@githost:simplegit + 049d078...fbff5bc master -> origin/master</code></pre> </div> </div> <div class="paragraph"> <p>Hierna ziet de lokale repository van John er ongeveer zo uit:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/small-team-1.png" alt="De afwijkende historie van John."> </div> <div class="title">Figuur 58. De afwijkende historie van John.</div> </div> <div class="paragraph"> <p>Nu kan John het werk van Jessica dat hij heeft gefetcht gaan mergen in zijn lokale werk.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git merge origin/master Merge made by the 'recursive' strategy. TODO | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Zo lang als de lokale merge gladjes verloopt, zal John’s geupdate history er zo uit zien:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/small-team-2.png" alt="De repository van John na `origin/master` te hebben gemerged."> </div> <div class="title">Figuur 59. De repository van John na <code>origin/master</code> te hebben gemerged.</div> </div> <div class="paragraph"> <p>Nu zou John zijn code moeten testen om er zeker van te zijn dat alles nog steeds goed werkt, en dan kan hij zijn nieuwe gemergede werk pushen naar de server:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git push origin master ... To john@githost:simplegit.git fbff5bc..72bbc59 master -> master</code></pre> </div> </div> <div class="paragraph"> <p>Uiteindelijk ziet de commit historie van John er zo uit:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/small-team-3.png" alt="De historie van John na te hebben gepusht naar de `origin` server."> </div> <div class="title">Figuur 60. De historie van John na te hebben gepusht naar de <code>origin</code> server.</div> </div> <div class="paragraph"> <p>In de tussentijd heeft Jessica een topic branch genaamd <code>issue54</code> aangemaakt en daar drie commits op gedaan. Ze heeft John’s wijzigingen nog niet opgehaald, dus haar commit historie ziet er zo uit:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/small-team-4.png" alt="Topic branch van Jessica."> </div> <div class="title">Figuur 61. Topic branch van Jessica.</div> </div> <div class="paragraph"> <p>Ineens hoort Jessica dat John nieuw werk heeft gepusht op de server en ze wil dit even gaan bekijken, zodat ze alle inhoud van de server kan ophalen dat ze nog niet heeft met:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Jessica's Machine $ git fetch origin ... From jessica@githost:simplegit fbff5bc..72bbc59 master -> origin/master</code></pre> </div> </div> <div class="paragraph"> <p>Dit haalt het werk op dat John in de tussentijd gepusht heeft. De historie van Jessica ziet er nu zo uit:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/small-team-5.png" alt="Historie van Jessica na het fetchen van de wijzigingen van John."> </div> <div class="title">Figuur 62. Historie van Jessica na het fetchen van de wijzigingen van John.</div> </div> <div class="paragraph"> <p>Jessica denkt dat haar topic branch nu klaar is, maar ze wil weten wat ze in haar werk moet mergen zodat ze kan pushen. Ze voert <code>git log</code> uit om dat uit te zoeken:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git log --no-merges issue54..origin/master commit 738ee872852dfaa9d6634e0dea7a324040193016 Author: John Smith <jsmith@example.com> Date: Fri May 29 16:01:27 2009 -0700 removed invalid default value</code></pre> </div> </div> <div class="paragraph"> <p>De <code>issue54..origin/master</code> syntax is een log filter dat Git vraagt om alleen de lijst van commits te tonen die op de laatstgenoemde branch (in dit geval <code>origin/master</code>) staan die niet in de eerstegenoemde (in dit geval <code>issue54</code>) staan. We zullen deze syntax in detail bespreken in <a href="/book/nl/v2/ch00/_commit_ranges">Commit reeksen</a>.</p> </div> <div class="paragraph"> <p>Nu zien we in de uitvoer dat er een commit is die John gemaakt heeft die Jessica nog niet gemerged heeft. Als ze <code>origin/master</code> merged, is dat de enige commit die haar lokale werk zal wijzigen.</p> </div> <div class="paragraph"> <p>Nu kan Jessica het werk van haar topic branch mergen in haar master branch, het werk van John (<code>origin/master</code>) in haar <code>master</code>-branch mergen, en dan naar de server pushen.</p> </div> <div class="paragraph"> <p>Eerst (nadat ze al haar werk op de <code>issue54</code> topic branch heeft gecommit) schakelt Jessica terug naar haar master branch als voorbereiding op het integreren van al dit werk:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git checkout master Switched to branch 'master' Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.</code></pre> </div> </div> <div class="paragraph"> <p>Ze kan <code>origin/master</code> of <code>issue54</code> als eerste mergen — ze zijn beide stroomopwaarts dus de volgorde maakt niet uit. Uiteindelijk zou de snapshot gelijk moeten zijn ongeacht welke volgorde ze kiest; alleen de geschiedenis zal iets verschillen. Ze kiest ervoor om <code>issue54</code> eerst te mergen:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git merge issue54 Updating fbff5bc..4af4298 Fast forward README | 1 + lib/simplegit.rb | 6 +++++- 2 files changed, 6 insertions(+), 1 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Er doen zich geen problemen voor, zoals je kunt zien was het een eenvoudige fast-forward. Jessica voltooit het lokale merge proces met het mergen van John’s eerder opgehaalde werk die in de <code>origin/master</code>-branch zit:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git merge origin/master Auto-merging lib/simplegit.rb Merge made by the 'recursive' strategy. lib/simplegit.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Alles merget netjes, en de historie van Jessica ziet er nu zo uit:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/small-team-6.png" alt="Historie van Jessica na het mergen van de wijzigingen van John."> </div> <div class="title">Figuur 63. Historie van Jessica na het mergen van de wijzigingen van John.</div> </div> <div class="paragraph"> <p>Nu is <code>origin/master</code> bereikbaar vanuit Jessica’s <code>master</code>-branch, dus ze zou in staat moeten zijn om succesvol te pushen (even aangenomen dat John in de tussentijd niet weer iets gepusht heeft):</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git push origin master ... To jessica@githost:simplegit.git 72bbc59..8059c15 master -> master</code></pre> </div> </div> <div class="paragraph"> <p>Iedere ontwikkelaar heeft een paar keer gecommit en elkaars werk succesvol gemerged.</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/small-team-7.png" alt="Historie van Jessica na al haar wijzigingen naar de server te hebben gepusht."> </div> <div class="title">Figuur 64. Historie van Jessica na al haar wijzigingen naar de server te hebben gepusht.</div> </div> <div class="paragraph"> <p>Dit is één van de eenvoudigste workflows. Je werkt een tijdje (over het algemeen in een topic branch) en merget dit in je <code>master</code>-branch als het klaar is om te worden geïntegreerd. Als je dat werk wilt delen, dan fetch merge je je eigen <code>master</code>-branch met de <code>origin/master</code> als die is gewijzigd, en als laatste push je naar de <code>master</code>-branch op de server. De algemene volgorde is als volgt:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/small-team-flow.png" alt="Algemene volgorde van gebeurtenissen voor een eenvoudige multi-ontwikkelaar Git workflow."> </div> <div class="title">Figuur 65. Algemene volgorde van gebeurtenissen voor een eenvoudige multi-ontwikkelaar Git workflow.</div> </div> </div> <div class="sect3"> <h3 id="_besloten_aangestuurd_team">Besloten aangestuurd team</h3> <div class="paragraph"> <p> In het volgende scenario zul je kijken naar de rol van de bijdragers in een grotere besloten groep. Je zult leren hoe te werken in een omgeving waar kleine groepen samenwerken aan functies, waarna die team-gebaseerde bijdragen worden geïntegreerd door een andere partij.</p> </div> <div class="paragraph"> <p>Stel dat John en Jessica samen werken aan een functie (laten we zeggen “featureA”), terwijl Jessica en een derde ontwikkelaar, Josie, aan een tweede (zeg, “featureB”) aan het werken zijn. In dit geval gebruikt het bedrijf een integratie-manager achtige workflow, waarbij het werk van de individuele groepen alleen wordt geïntegreerd door bepaalde ontwikkelaars, en de <code>master</code>-branch van het hoofd repo alleen kan worden vernieuwd door die ontwikkelaars. In dit scenario wordt al het werk gedaan in team-gebaseerde branches en later door de integrators samengevoegd.</p> </div> <div class="paragraph"> <p>Laten we Jessica’s workflow volgen terwijl ze aan haar twee features werkt, in parallel met twee verschillende ontwikkelaars in deze omgeving. We nemen even aan dat ze haar repository al gekloond heeft, en dat ze besloten heeft als eerste te werken aan <code>featureA</code>. Ze maakt een nieuwe branch aan voor de functie en doet daar wat werk:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Jessica's Machine $ git checkout -b featureA Switched to a new branch 'featureA' $ vim lib/simplegit.rb $ git commit -am 'add limit to log function' [featureA 3300904] add limit to log function 1 files changed, 1 insertions(+), 1 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Op dit punt, moet ze haar werk delen met John, dus ze pusht haar commits naar de <code>featureA</code>-branch op de server. Jessica heeft geen push toegang op de <code>master</code>-branch — alleen de integratoren hebben dat — dus ze moet naar een andere branch pushen om samen te kunnen werken met John:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git push -u origin featureA ... To jessica@githost:simplegit.git * [new branch] featureA -> featureA</code></pre> </div> </div> <div class="paragraph"> <p>Jessica mailt John om hem te zeggen dat ze wat werk gepusht heeft in een branch genaamd <code>featureA</code> en dat hij er nu naar kan kijken. Terwijl ze op terugkoppeling van John wacht, besluit Jessica te beginnen met het werken aan <code>featureB</code> met Josie. Om te beginnen start ze een nieuwe feature branch, gebaseerd op de <code>master</code>-branch van de server:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Jessica's Machine $ git fetch origin $ git checkout -b featureB origin/master Switched to a new branch 'featureB'</code></pre> </div> </div> <div class="paragraph"> <p>Nu doet Jessica een paar commits op de <code>featureB</code>-branch:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ vim lib/simplegit.rb $ git commit -am 'made the ls-tree function recursive' [featureB e5b0fdc] made the ls-tree function recursive 1 files changed, 1 insertions(+), 1 deletions(-) $ vim lib/simplegit.rb $ git commit -am 'add ls-files' [featureB 8512791] add ls-files 1 files changed, 5 insertions(+), 0 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Jessica’s repository ziet eruit als volgt:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/managed-team-1.png" alt="Initiële commit historie van Jessica."> </div> <div class="title">Figuur 66. Initiële commit historie van Jessica.</div> </div> <div class="paragraph"> <p>Ze is klaar om haar werk te pushen, maar ze krijgt een mail van Josie dat een branch met wat initieel werk voor <code>featureB</code> erin al gepusht is naar de server in de <code>featureBee</code>-branch. Jessica moet die wijzigingen eerst mergen met die van haar voordat ze kan pushen naar de server. Ze kan dan Josie’s wijzigingen ophalen met <code>git fetch</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git fetch origin ... From jessica@githost:simplegit * [new branch] featureBee -> origin/featureBee</code></pre> </div> </div> <div class="paragraph"> <p>Aangenomen dat Jessica nog op haar uitgecheckte <code>featureB</code>-branch zit, kan Jessica kan dit nu mergen in het werk wat zij gedaan heeft met <code>git merge</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git merge origin/featureBee Auto-merging lib/simplegit.rb Merge made by the 'recursive' strategy. lib/simplegit.rb | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Nu wil Jessica al dit gemergede “featureB” werk terug pushen naar de server, maar ze wil niet eenvoudigweg haar eigen <code>featureB</code>-branch pushen. Omdat Josie al een <code>featureBee</code>-branch gemaakt heeft, zou Jessica op <em>die</em> branch willen pushen en dat doet ze met:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git push -u origin featureB:featureBee ... To jessica@githost:simplegit.git fba9af8..cd685d1 featureB -> featureBee</code></pre> </div> </div> <div class="paragraph"> <p>Dit wordt een <em>refspec</em> genoemd. Zie <a href="/book/nl/v2/ch00/_refspec">De Refspec</a> voor een meer gedetailleerde behandeling van Git refspecs en de verschillende dingen die je daarmee kan doen. Merk ook de <code>-u</code> vlag op; dit is een verkorte notatie voor <code>-set-upstream</code>, wat de branches voor eenvoudigere pushen en pullen op een later moment inricht.</p> </div> <div class="paragraph"> <p>Plotseling mailt John naar Jessica om te zeggen dat hij wat wijzigingen naar de <code>featureA</code>-branch waar ze op samenwerken gepusht heeft, om haar te vragen die te bekijken. Wederom voert Jessica een eenvoudige <code>git fetch</code> uit om <em>alle</em> nieuwe wijzigingen van de server op te halen, inclusief (uiteraard) het werk van John:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git fetch origin ... From jessica@githost:simplegit 3300904..aad881d featureA -> origin/featureA</code></pre> </div> </div> <div class="paragraph"> <p>Jessica kan de log bekijken van John’s nieuwe werk door de inhoud van de zojuist opgehaalde <code>featureA</code>-branch met haar lokale kopie van dezelfde branch:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git log featureA..origin/featureA commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 Author: John Smith <jsmith@example.com> Date: Fri May 29 19:57:33 2009 -0700 changed log output to 30 from 25</code></pre> </div> </div> <div class="paragraph"> <p>Als wat Jessica ziet haar bevalt, kan ze het nieuwe werk van John in haar lokale <code>featureA</code>-branch mergen met:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git checkout featureA Switched to branch 'featureA' $ git merge origin/featureA Updating 3300904..aad881d Fast forward lib/simplegit.rb | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Jessica kan tot slot nog wat kleine wijzigingen aanbrengen in de gemergede inhoud, dus ze het staat haar vrij om dat te doen, deze wijzigingen committen in haar lokale <code>featureA</code>-branch en dan het eindresultaat terug pushen op de server.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git commit -am 'small tweak' [featureA 774b3ed] small tweak 1 files changed, 1 insertions(+), 1 deletions(-) $ git push ... To jessica@githost:simplegit.git 3300904..774b3ed featureA -> featureA</code></pre> </div> </div> <div class="paragraph"> <p>De commit historie van Jessica ziet er nu zo uit:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/managed-team-2.png" alt="De historie van Jessica na het committen op een feature branch."> </div> <div class="title">Figuur 67. De historie van Jessica na het committen op een feature branch.</div> </div> <div class="paragraph"> <p>Jessica, Josie en John informeren de integrators nu dat de <code>featureA</code> en <code>featureBee</code>-branches op de server klaar zijn voor integratie in de hoofdlijn. Nadat zij die branches in de hoofdlijn geïntegreerd hebben, zal een fetch de nieuwe merge commits ophalen, waardoor de commit historie er zo uit ziet:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/managed-team-3.png" alt="De historie van Jessica na het mergen van haar beide topic branches."> </div> <div class="title">Figuur 68. De historie van Jessica na het mergen van haar beide topic branches.</div> </div> <div class="paragraph"> <p>Veel groepen schakelen om naar Git juist vanwege de mogelijkheid om meerdere teams in parallel te kunnen laten werken, waarbij de verschillende lijnen van werk laat in het proces gemerged worden. De mogelijkheid van kleinere subgroepen of een team om samen te werken via remote branches zonder het hele team erin te betrekken of te hinderen is een enorm voordeel van Git. De volgorde van de workflow die je hier zag is ongeveer dit:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/managed-team-flow.png" alt="Eenvoudige volgorde in de workflow van dit aangestuurde team."> </div> <div class="title">Figuur 69. Eenvoudige volgorde in de workflow van dit aangestuurde team.</div> </div> </div> <div class="sect3"> <h3 id="_public_project">Gevorkt openbaar project</h3> <div class="paragraph"> <p> Het bijdragen aan openbare, of publieke, projecten gaat op een iets andere manier. Omdat je niet de toestemming hebt om de branches van het project rechtstreeks te updaten, moet je het werk op een andere manier naar de beheerders krijgen. Dit eerste voorbeeld beschrijft het bijdragen via afsplitsen (forken) op Git hosts die het eenvoudig aanmaken van forks ondersteunen. Vele hosting sites ondersteunen dit (waaronder GitHub, BitBucket, Google Code, repo.or.cz, en andere), en veel project beheerders verwachten deze manier van bijdragen. De volgende paragraaf behandelt projecten die de voorkeur hebben om bijdragen in de vorm van patches via e-mail te ontvangen.</p> </div> <div class="paragraph"> <p>Eerst zal je waarschijnlijk de hoofdrepository klonen, een topic branch maken voor de patch of reeks patches die je van plan bent bij te dragen, en je werk daarop doen. De te volgen stappen zien er in principe zo uit:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git clone <url> $ cd project $ git checkout -b featureA ... work ... $ git commit ... work ... $ git commit</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Noot</div> </td> <td class="content"> <div class="paragraph"> <p>Je kunt eventueel besluiten <code>rebase -i</code> te gebruiken om je werk in één enkele commit samen te persen (squash), of het werk in de commits te herschikken om de patch eenvoudiger te kunnen laten reviewen door de beheerders — zie <a href="/book/nl/v2/ch00/_rewriting_history">Geschiedenis herschrijven</a> voor meer informatie over het interactief rebasen.</p> </div> </td> </tr> </table> </div> <div class="paragraph"> <p>Als je werk op de branch af is, en je klaar bent om het over te dragen aan de beheerders, ga je naar de originele project pagina en klik op de “Fork” knop. Hiermee maak je een eigen overschrijfbare fork van het project. Je moet de URL van deze nieuwe repository URL toevoegen als een tweede remote, en laten we deze <code>myfork</code> noemen:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git remote add myfork <url></code></pre> </div> </div> <div class="paragraph"> <p>Dan moet je je werk daar naartoe pushen. Het is het makkelijkst om de topic branch waar je op zit te werken te pushen naar je repository, in plaats van het te mergen in je master branch en die te pushen. De reden hiervan is, dat als het werk niet wordt geaccepteerd of alleen ge-cherry picked (deels overgenomen), je jouw master branch niet hoeft terug te draaien (de Git <code>cherry-pick</code> operatie wordt meer gedetailleerd behandeld in <a href="/book/nl/v2/ch00/_rebase_cherry_pick">Rebasende en cherry pick workflows</a>). Als de beheerders je werk mergen, rebasen of cherry picken, dan krijg je het uiteindelijk toch binnen door hun repository te pullen.</p> </div> <div class="paragraph"> <p>Hoe dan ook, je kunt je werk pushen met:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git push -u myfork featureA</code></pre> </div> </div> <div class="paragraph"> <p> Als jouw werk gepusht is naar jouw fork van de repository, dan moet je de beheerder van het oorspronkelijke project inlichten dat je werk hebt dat je ze wil laten mergen. Dit wordt een <em>pull request</em> (haal-binnen-verzoek) genoemd, en je kunt deze via de website genereren - GitHub heeft een eigen “Pull Request” mechanisme die we verder zullen behandelen in <a href="/book/nl/v2/ch00/ch06-github">GitHub</a> of je roept het <code>git request-pull</code> commando aan en stuurt een mail met de uitvoer handmatig naar de projectbeheerder.</p> </div> <div class="paragraph"> <p>Het <code>request-pull</code> commando neemt de basis branch waarin je de topic branch gepulld wil krijgen, en de URL van de Git repository waar je ze uit wil laten pullen, en maakt een samenvatting van alle wijzigingen die je gepulld wenst te hebben. Bijvoorbeeld, als Jessica John een pull request wil sturen, en ze heeft twee commits gedaan op de topic branch die ze zojuist gepusht heeft, dan kan ze dit uitvoeren:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git request-pull origin/master myfork The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: Jessica Smith (1): added a new function are available in the git repository at: git://githost/simplegit.git featureA Jessica Smith (2): add limit to log function change log output to 30 from 25 lib/simplegit.rb | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>De uitvoer kan naar de beheerders gestuurd worden — het vertelt ze waar het werk vanaf gebrancht is, vat de commits samen en vertelt waar vandaan ze dit werk kunnen pullen.</p> </div> <div class="paragraph"> <p>Bij een project waarvan je niet de beheerder bent, is het over het algemeen eenvoudiger om een branch zoals <code>master</code> altijd de <code>origin/master</code> te laten tracken, en je werk te doen in topic branches die je eenvoudig weg kunt gooien als ze geweigerd worden. Als je je werkthema’s gescheiden houdt in topic branches maakt dat het ook eenvoudiger voor jou om je werk te rebasen als de punt van de hoofd-repository in de tussentijd verschoven is en je commits niet langer netjes toegepast kunnen worden. Bijvoorbeeld, als je een tweede onderwerp wilt bijdragen aan een project, ga dan niet verder werken op de topic branch die je zojuist gepusht hebt — begin opnieuw vanaf de <code>master</code>-branch van de hoofd repository:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git checkout -b featureB origin/master ... work ... $ git commit $ git push myfork featureB $ git request-pull origin/master myfork ... email generated request pull to maintainer ... $ git fetch origin</code></pre> </div> </div> <div class="paragraph"> <p>Nu zijn al je onderwerpen opgeslagen in een silo — vergelijkbaar met een patch reeks (queue) — die je kunt herschrijven, rebasen en wijzigen zonder dat de onderwerpen elkaar beïnvloeden of van elkaar afhankelijk, hier is hoe je het kunt doen:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/public-small-1.png" alt="Initiële commit historie met werk van `featureB`."> </div> <div class="title">Figuur 70. Initiële commit historie met werk van <code>featureB</code>.</div> </div> <div class="paragraph"> <p>Stel dat de project-beheerder een verzameling andere patches binnengehaald heeft en jouw eerste branch geprobeerd heeft, maar dat die niet meer netjes merged. In dat geval kun je proberen die branch te rebasen op <code>origin/master</code>, de conflicten op te lossen voor de beheerder, en dan je wijzigingen opnieuw aanbieden:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git checkout featureA $ git rebase origin/master $ git push -f myfork featureA</code></pre> </div> </div> <div class="paragraph"> <p>Dit herschrijft je historie zodat die eruit ziet als in <a href="/book/nl/v2/ch00/psp_b">Commit historie na werk van <code>featureA</code>.</a>.</p> </div> <div id="psp_b" class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/public-small-2.png" alt="Commit historie na werk van `featureA`."> </div> <div class="title">Figuur 71. Commit historie na werk van <code>featureA</code>.</div> </div> <div class="paragraph"> <p>Omdat je de branch gerebased hebt, moet je de <code>-f</code> specificeren met je push commando om in staat te zijn de <code>featureA</code>-branch op de server te vervangen met een commit die er geen afstammeling van is. Een alternatief zou zijn dit nieuwe werk naar een andere branch op de server te pushen (misschien <code>featureAv2</code> genaamd).</p> </div> <div class="paragraph"> <p>Laten we eens kijken naar nog een mogelijk scenario: de beheerder heeft je werk bekeken in je tweede branch en vindt het concept goed, maar zou willen dat je een implementatie detail verandert. Je gebruikt deze gelegenheid meteen om het werk te baseren op de huidige <code>master</code>-branch van het project. Je begint een nieuwe branch gebaseerd op de huidige <code>origin/master</code>-branch, squasht de <code>featureB</code> wijzigingen er naartoe, lost eventuele conflicten op, doet de implementatie wijziging en pusht deze terug als een nieuwe branch:</p> </div> <div class="paragraph"> <p></p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git checkout -b featureBv2 origin/master $ git merge --squash featureB ... change implementation ... $ git commit $ git push myfork featureBv2</code></pre> </div> </div> <div class="paragraph"> <p>De <code>--squash</code> optie pakt al het werk op de gemergde branch en perst dat samen in één wijzigingsset (changeset) die de staat van de repository geeft alsof er een echte merge zou hebben plaatsgevonden, zonder feitelijk een merge commit te doen. Dit betekent dat je toekomstige commit maar één ouder heeft en geeft je de ruimte om alle wijzigingen te introduceren uit een andere branch en daarna meer wijzigingen te maken voordat de nieuwe commit wordt vastgelegd. Daarnaast kan de <code>--no-commit</code> handig zijn door de merge commit uit te stellen in plaats van het standaard merge proces.</p> </div> <div class="paragraph"> <p>Je kunt de beheerder nu een bericht sturen dat je de gevraagde wijzigingen gemaakt hebt en dat ze die wijzigingen kunnen vinden in je <code>featureBv2</code>-branch.</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/nl/v2/images/public-small-3.png" alt="Commit historie na het `featureBv2` werk."> </div> <div class="title">Figuur 72. Commit historie na het <code>featureBv2</code> werk.</div> </div> </div> <div class="sect3"> <h3 id="_project_over_email">Openbaar project per e-mail</h3> <div class="paragraph"> <p> Veel projecten hebben vastgestelde procedures voor het accepteren van patches — je zult de specifieke regels voor elk project moeten controleren, ze zullen namelijk verschillen. Omdat er verscheidene oudere, grotere projecten zijn die patches accepteren via ontwikkelaar-maillijsten, zullen we nu een voorbeeld hiervan behandelen.</p> </div> <div class="paragraph"> <p>De workflow is vergelijkbaar met het vorige geval — je maakt topic branches voor iedere patch waar je aan werkt. Het verschil is hoe je die aanlevert bij het project. In plaats van het project te forken en naar je eigen schrijfbare versie te pushen, genereer je e-mail versies van iedere reeks commits en mailt die naar de ontwikkelaar-maillijst:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git checkout -b topicA ... work ... $ git commit ... work ... $ git commit</code></pre> </div> </div> <div class="paragraph"> <p> Nu heb je twee commits die je naar de maillijst wilt sturen. Je gebruikt <code>git format-patch</code> om de mbox-geformatteerde bestanden te genereren die je kunt mailen naar de lijst. Dit maakt van iedere commit een e-mail bericht met de eerste regel van het commit bericht als het onderwerp, en de rest van het bericht plus de patch die door de commit wordt geïntroduceerd als de inhoud. Het prettige hieraan is dat met het toepassen van een patch uit een mail die gegenereerd is met <code>format-patch</code> alle commit informatie blijft behouden.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git format-patch -M origin/master 0001-add-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch</code></pre> </div> </div> <div class="paragraph"> <p>Het <code>format-patch</code> commando drukt de namen af van de patch bestanden die het maakt. De <code>-M</code> optie vertelt Git te letten op naamswijzigingen. De bestanden komen er uiteindelijk zo uit te zien:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith <jessica@example.com> Date: Sun, 6 Apr 2008 10:17:23 -0700 Subject: [PATCH 1/2] add limit to log function Limit log functionality to the first 20 --- lib/simplegit.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/lib/simplegit.rb b/lib/simplegit.rb index 76f47bc..f9815f1 100644 --- a/lib/simplegit.rb +++ b/lib/simplegit.rb @@ -14,7 +14,7 @@ class SimpleGit end def log(treeish = 'master') - command("git log #{treeish}") + command("git log -n 20 #{treeish}") end def ls_tree(treeish = 'master') -- 2.1.0</code></pre> </div> </div> <div class="paragraph"> <p>Je kunt deze patch bestanden ook aanpassen om meer informatie, die je niet in het commit bericht wilt laten verschijnen, voor de maillijst toe te voegen. Als je tekst toevoegt tussen de <code>---</code> regel en het begin van de patch (de <code>diff --git</code> regel), dan kunnen ontwikkelaars dit lezen, maar tijdens het toepassen van de patch wordt dit genegeerd.</p> </div> <div class="paragraph"> <p>Om dit te mailen naar een maillijst, kan je het bestand in je mail-applicatie plakken of het sturen via een commandoregel programma. Het plakken van de tekst veroorzaakt vaak formaterings problemen, in het bijzonder bij “slimmere” clients die de newlines en andere witruimte niet juist behouden. Gelukkig levert Git een gereedschap die je helpt om juist geformatteerde patches via IMAP te versturen, wat het alweer een stuk makkelijker voor je kan maken. We zullen je laten zien hoe je een patch via Gmail stuurt, wat de mail-applicatie is waar we het meest bekend mee zijn. Je kunt gedetailleerde instructies voor een aantal mail programma’s vinden aan het eind van het eerder genoemde <code>Documentation/SubmittingPatches</code> bestand in de Git broncode.</p> </div> <div class="paragraph"> <p> Eerst moet je de imap sectie in je <code>~/.gitconfig</code> bestand instellen. Je kunt iedere waarde apart instellen met een serie <code>git config</code> commando’s, of je kunt ze handmatig toevoegen, maar uiteindelijk moet je config bestand er ongeveer zo uitzien:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-ini" data-lang="ini">[imap] folder = "[Gmail]/Drafts" host = imaps://imap.gmail.com user = user@gmail.com pass = YX]8g76G_2^sFbd port = 993 sslverify = false</code></pre> </div> </div> <div class="paragraph"> <p>Als je IMAP server geen SSL gebruikt, zijn de laatste twee regels waarschijnlijk niet nodig, en de waarde voor host zal <code>imap://</code> zijn in plaats van <code>imaps://</code>. Als dat ingesteld is, kun je <code>git imap-send</code> gebruiken om de patch reeks in de Drafts map van de gespecificeerde IMAP server te zetten:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ cat *.patch |git imap-send Resolving imap.gmail.com... ok Connecting to [74.125.142.109]:993... ok Logging in... sending 2 messages 100% (2/2) done</code></pre> </div> </div> <div class="paragraph"> <p>Nu zou je in staat moeten zijn om naar je Drafts folder te gaan, het To veld te veranderen in het adres van de mail lijst waar je de patch naar toe stuurt, en mogelijk de onderhouder of de persoon verantwoordelijk voor dat deel te CC-en, en het te versturen.</p> </div> <div class="paragraph"> <p>Je kunt de patches ook via een SMTP server sturen. Net als hierboven, kan je elke waarde apart zetten met een reeks van <code>git config</code> commando’s, of je kunt ze handmatig in de sendemail sectie in je <code>~/.gitconfig</code> bestand toevoegen:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-ini" data-lang="ini">[sendemail] smtpencryption = tls smtpserver = smtp.gmail.com smtpuser = user@gmail.com smtpserverport = 587</code></pre> </div> </div> <div class="paragraph"> <p>Als dit gedaan is, kan je <code>git send-email</code> gebruiken om je patches te sturen:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] Emails will be sent from: Jessica Smith <jessica@example.com> Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y</code></pre> </div> </div> <div class="paragraph"> <p>Dan zal Git een berg log-informatie oplepelen die er ongeveer zo uitziet voor elke patch die je aan het versturen bent:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-text" data-lang="text">(mbox) Adding cc: Jessica Smith <jessica@example.com> from \line 'From: Jessica Smith <jessica@example.com>' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com From: Jessica Smith <jessica@example.com> To: jessica@example.com Subject: [PATCH 1/2] added limit to log function Date: Sat, 30 May 2009 13:29:15 -0700 Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty In-Reply-To: <y> References: <y> Result: OK</code></pre> </div> </div> </div> <div class="sect3"> <h3 id="_samenvatting_5">Samenvatting</h3> <div class="paragraph"> <p>In dit hoofdstuk is een aantal veel voorkomende workflows behandeld, die je kunt gebruiken om te kunnen werken in een aantal zeer verschillende typen Git projecten die je kunt tegenkomen. En er zijn een aantal nieuwe gereedschappen geïntroduceerd die je helpen om dit proces te beheren. Wat hierna volgt zal je laten zien hoe je aan de andere kant van de tafel werkt: een Git project beheren. Je zult leren hoe een welwillende dictator of integratie manager te zijn.</p> </div> </div> <div id="nav"><a href="/book/nl/v2/Gedistribueerd-Git-Gedistribueerde-workflows">prev</a> | <a href="/book/nl/v2/Gedistribueerd-Git-Het-beheren-van-een-project">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>