CINXE.COM
Git - Wgrywanie zmian do projektu
<!DOCTYPE html> <html lang="pl"> <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 - Wgrywanie zmian do projektu</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/progit2-pl/progit2-pl">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/pl/v2/Pierwsze-kroki-Wprowadzenie-do-kontroli-wersji">Pierwsze kroki</a></h2> <ol> <li> 1.1 <a href="/book/pl/v2/Pierwsze-kroki-Wprowadzenie-do-kontroli-wersji">Wprowadzenie do kontroli wersji</a> </li> <li> 1.2 <a href="/book/pl/v2/Pierwsze-kroki-Kr%c3%b3tka-historia-Git">Krótka historia Git</a> </li> <li> 1.3 <a href="/book/pl/v2/Pierwsze-kroki-Podstawy-Git">Podstawy Git</a> </li> <li> 1.4 <a href="/book/pl/v2/Pierwsze-kroki-Linia-polece%c5%84">Linia poleceń</a> </li> <li> 1.5 <a href="/book/pl/v2/Pierwsze-kroki-Instalacja-Git">Instalacja Git</a> </li> <li> 1.6 <a href="/book/pl/v2/Pierwsze-kroki-Wst%c4%99pna-konfiguracja-Git">Wstępna konfiguracja Git</a> </li> <li> 1.7 <a href="/book/pl/v2/Pierwsze-kroki-Uzyskiwanie-pomocy">Uzyskiwanie pomocy</a> </li> <li> 1.8 <a href="/book/pl/v2/Pierwsze-kroki-Podsumowanie">Podsumowanie</a> </li> </ol> </li> <li class='chapter'> <h2>2. <a href="/book/pl/v2/Podstawy-Gita-Pierwsze-repozytorium-Gita">Podstawy Gita</a></h2> <ol> <li> 2.1 <a href="/book/pl/v2/Podstawy-Gita-Pierwsze-repozytorium-Gita">Pierwsze repozytorium Gita</a> </li> <li> 2.2 <a href="/book/pl/v2/Podstawy-Gita-Rejestrowanie-zmian-w-repozytorium">Rejestrowanie zmian w repozytorium</a> </li> <li> 2.3 <a href="/book/pl/v2/Podstawy-Gita-Podgl%c4%85d-historii-rewizji">Podgląd historii rewizji</a> </li> <li> 2.4 <a href="/book/pl/v2/Podstawy-Gita-Cofanie-zmian">Cofanie zmian</a> </li> <li> 2.5 <a href="/book/pl/v2/Podstawy-Gita-Praca-ze-zdalnym-repozytorium">Praca ze zdalnym repozytorium</a> </li> <li> 2.6 <a href="/book/pl/v2/Podstawy-Gita-Tagowanie">Tagowanie</a> </li> <li> 2.7 <a href="/book/pl/v2/Podstawy-Gita-Aliasy">Aliasy</a> </li> <li> 2.8 <a href="/book/pl/v2/Podstawy-Gita-Podsumowanie">Podsumowanie</a> </li> </ol> </li> <li class='chapter'> <h2>3. <a href="/book/pl/v2/Ga%c5%82%c4%99zie-Gita-Czym-jest-ga%c5%82%c4%85%c5%ba">Gałęzie Gita</a></h2> <ol> <li> 3.1 <a href="/book/pl/v2/Ga%c5%82%c4%99zie-Gita-Czym-jest-ga%c5%82%c4%85%c5%ba">Czym jest gałąź</a> </li> <li> 3.2 <a href="/book/pl/v2/Ga%c5%82%c4%99zie-Gita-Podstawy-rozga%c5%82%c4%99ziania-i-scalania">Podstawy rozgałęziania i scalania</a> </li> <li> 3.3 <a href="/book/pl/v2/Ga%c5%82%c4%99zie-Gita-Zarz%c4%85dzanie-ga%c5%82%c4%99ziami">Zarządzanie gałęziami</a> </li> <li> 3.4 <a href="/book/pl/v2/Ga%c5%82%c4%99zie-Gita-Sposoby-pracy-z-ga%c5%82%c4%99ziami">Sposoby pracy z gałęziami</a> </li> <li> 3.5 <a href="/book/pl/v2/Ga%c5%82%c4%99zie-Gita-Ga%c5%82%c4%99zie-zdalne">Gałęzie zdalne</a> </li> <li> 3.6 <a href="/book/pl/v2/Ga%c5%82%c4%99zie-Gita-Zmiana-bazy">Zmiana bazy</a> </li> <li> 3.7 <a href="/book/pl/v2/Ga%c5%82%c4%99zie-Gita-Podsumowanie">Podsumowanie</a> </li> </ol> </li> <li class='chapter'> <h2>4. <a href="/book/pl/v2/Git-na-serwerze-Protoko%c5%82y">Git na serwerze</a></h2> <ol> <li> 4.1 <a href="/book/pl/v2/Git-na-serwerze-Protoko%c5%82y">Protokoły</a> </li> <li> 4.2 <a href="/book/pl/v2/Git-na-serwerze-Uruchomienie-Git-na-serwerze">Uruchomienie Git na serwerze</a> </li> <li> 4.3 <a href="/book/pl/v2/Git-na-serwerze-Generowanie-Twojego-publicznego-klucza-SSH">Generowanie Twojego publicznego klucza SSH</a> </li> <li> 4.4 <a href="/book/pl/v2/Git-na-serwerze-Konfigurowanie-serwera">Konfigurowanie serwera</a> </li> <li> 4.5 <a href="/book/pl/v2/Git-na-serwerze-Git-Daemon">Git Daemon</a> </li> <li> 4.6 <a href="/book/pl/v2/Git-na-serwerze-Smart-HTTP">Smart HTTP</a> </li> <li> 4.7 <a href="/book/pl/v2/Git-na-serwerze-GitWeb">GitWeb</a> </li> <li> 4.8 <a href="/book/pl/v2/Git-na-serwerze-GitLab">GitLab</a> </li> <li> 4.9 <a href="/book/pl/v2/Git-na-serwerze-Inne-opcje-hostowania-przez-podmioty-zewn%c4%99trzne">Inne opcje hostowania przez podmioty zewnętrzne</a> </li> <li> 4.10 <a href="/book/pl/v2/Git-na-serwerze-Podsumowanie">Podsumowanie</a> </li> </ol> </li> <li class='chapter'> <h2>5. <a href="/book/pl/v2/Rozproszony-Git-Rozproszone-przep%c5%82ywy-pracy">Rozproszony Git</a></h2> <ol> <li> 5.1 <a href="/book/pl/v2/Rozproszony-Git-Rozproszone-przep%c5%82ywy-pracy">Rozproszone przepływy pracy</a> </li> <li> 5.2 <a href="/book/pl/v2/Rozproszony-Git-Wgrywanie-zmian-do-projektu" class="active">Wgrywanie zmian do projektu</a> </li> <li> 5.3 <a href="/book/pl/v2/Rozproszony-Git-Utrzymywanie-projektu">Utrzymywanie projektu</a> </li> <li> 5.4 <a href="/book/pl/v2/Rozproszony-Git-Podsumowanie">Podsumowanie</a> </li> </ol> </li> </ol> </div> <div class='column-middle'> <ol class='book-toc'> <li class='chapter'> <h2>6. <a href="/book/pl/v2/GitHub-Account-Setup-and-Configuration">GitHub</a></h2> <ol> <li> 6.1 <a href="/book/pl/v2/GitHub-Account-Setup-and-Configuration">Account Setup and Configuration</a> </li> <li> 6.2 <a href="/book/pl/v2/GitHub-Contributing-to-a-Project">Contributing to a Project</a> </li> <li> 6.3 <a href="/book/pl/v2/GitHub-Maintaining-a-Project">Maintaining a Project</a> </li> <li> 6.4 <a href="/book/pl/v2/GitHub-Managing-an-organization">Managing an organization</a> </li> <li> 6.5 <a href="/book/pl/v2/GitHub-Scripting-GitHub">Scripting GitHub</a> </li> <li> 6.6 <a href="/book/pl/v2/GitHub-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>7. <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Wskazywanie-rewizji">Narzędzia Gita</a></h2> <ol> <li> 7.1 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Wskazywanie-rewizji">Wskazywanie rewizji</a> </li> <li> 7.2 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Interaktywne-u%c5%bcywanie-przechowali">Interaktywne używanie przechowali</a> </li> <li> 7.3 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Schowek-i-czyszczenie">Schowek i czyszczenie</a> </li> <li> 7.4 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Signing-Your-Work">Signing Your Work</a> </li> <li> 7.5 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Searching">Searching</a> </li> <li> 7.6 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Przepisywanie-historii">Przepisywanie historii</a> </li> <li> 7.7 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Reset-Demystified">Reset Demystified</a> </li> <li> 7.8 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Advanced-Merging">Advanced Merging</a> </li> <li> 7.9 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Rerere">Rerere</a> </li> <li> 7.10 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Debugowanie-z-Gitem">Debugowanie z Gitem</a> </li> <li> 7.11 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Modu%c5%82y-zale%c5%bcne">Moduły zależne</a> </li> <li> 7.12 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Bundling">Bundling</a> </li> <li> 7.13 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Replace">Replace</a> </li> <li> 7.14 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Credential-Storage">Credential Storage</a> </li> <li> 7.15 <a href="/book/pl/v2/Narz%c4%99dzia-Gita-Podsumowanie">Podsumowanie</a> </li> </ol> </li> <li class='chapter'> <h2>8. <a href="/book/pl/v2/Dostosowywanie-Gita-Konfiguracja-Gita">Dostosowywanie Gita</a></h2> <ol> <li> 8.1 <a href="/book/pl/v2/Dostosowywanie-Gita-Konfiguracja-Gita">Konfiguracja Gita</a> </li> <li> 8.2 <a href="/book/pl/v2/Dostosowywanie-Gita-Git-Attributes">Git Attributes</a> </li> <li> 8.3 <a href="/book/pl/v2/Dostosowywanie-Gita-Git-Hooks">Git Hooks</a> </li> <li> 8.4 <a href="/book/pl/v2/Dostosowywanie-Gita-An-Example-Git-Enforced-Policy">An Example Git-Enforced Policy</a> </li> <li> 8.5 <a href="/book/pl/v2/Dostosowywanie-Gita-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>9. <a href="/book/pl/v2/Git-i-inne-systemy-Git-jako-klient">Git i inne systemy</a></h2> <ol> <li> 9.1 <a href="/book/pl/v2/Git-i-inne-systemy-Git-jako-klient">Git jako klient</a> </li> <li> 9.2 <a href="/book/pl/v2/Git-i-inne-systemy-Migracja-do-Gita">Migracja do Gita</a> </li> <li> 9.3 <a href="/book/pl/v2/Git-i-inne-systemy-Podsumowanie">Podsumowanie</a> </li> </ol> </li> <li class='chapter'> <h2>10. <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Komendy-typu-plumbing-i-porcelain">Mechanizmy wewnętrzne w Git</a></h2> <ol> <li> 10.1 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Komendy-typu-plumbing-i-porcelain">Komendy typu plumbing i porcelain</a> </li> <li> 10.2 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Obiekty-Gita">Obiekty Gita</a> </li> <li> 10.3 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Referencje-w-Git">Referencje w Git</a> </li> <li> 10.4 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Spakowane-pliki-packfiles">Spakowane pliki (packfiles)</a> </li> <li> 10.5 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Refspec">Refspec</a> </li> <li> 10.6 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Protoko%c5%82y-transferu">Protokoły transferu</a> </li> <li> 10.7 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Konserwacja-i-odzyskiwanie-danych">Konserwacja i odzyskiwanie danych</a> </li> <li> 10.8 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Environment-Variables">Environment Variables</a> </li> <li> 10.9 <a href="/book/pl/v2/Mechanizmy-wewn%c4%99trzne-w-Git-Podsumowanie">Podsumowanie</a> </li> </ol> </li> </ol> </div> <div class='column-right'> <ol class='book-toc'> <li class='chapter'> <h2>A1. <a href="/book/pl/v2/Appendix-A:-Git-in-Other-Environments-Graphical-Interfaces">Appendix A: Git in Other Environments</a></h2> <ol> <li> A1.1 <a href="/book/pl/v2/Appendix-A:-Git-in-Other-Environments-Graphical-Interfaces">Graphical Interfaces</a> </li> <li> A1.2 <a href="/book/pl/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Visual-Studio">Git in Visual Studio</a> </li> <li> A1.3 <a href="/book/pl/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Eclipse">Git in Eclipse</a> </li> <li> A1.4 <a href="/book/pl/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Bash">Git in Bash</a> </li> <li> A1.5 <a href="/book/pl/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Zsh">Git in Zsh</a> </li> <li> A1.6 <a href="/book/pl/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Powershell">Git in Powershell</a> </li> <li> A1.7 <a href="/book/pl/v2/Appendix-A:-Git-in-Other-Environments-Summary">Summary</a> </li> </ol> </li> <li class='chapter'> <h2>A2. <a href="/book/pl/v2/Appendix-B:-Embedding-Git-in-your-Applications-Command-line-Git">Appendix B: Embedding Git in your Applications</a></h2> <ol> <li> A2.1 <a href="/book/pl/v2/Appendix-B:-Embedding-Git-in-your-Applications-Command-line-Git">Command-line Git</a> </li> <li> A2.2 <a href="/book/pl/v2/Appendix-B:-Embedding-Git-in-your-Applications-Libgit2">Libgit2</a> </li> <li> A2.3 <a href="/book/pl/v2/Appendix-B:-Embedding-Git-in-your-Applications-JGit">JGit</a> </li> </ol> </li> <li class='chapter'> <h2>A3. <a href="/book/pl/v2/Appendix-C:-Git-Commands-Setup-and-Config">Appendix C: Git Commands</a></h2> <ol> <li> A3.1 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Setup-and-Config">Setup and Config</a> </li> <li> A3.2 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Getting-and-Creating-Projects">Getting and Creating Projects</a> </li> <li> A3.3 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Basic-Snapshotting">Basic Snapshotting</a> </li> <li> A3.4 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Branching-and-Merging">Branching and Merging</a> </li> <li> A3.5 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Sharing-and-Updating-Projects">Sharing and Updating Projects</a> </li> <li> A3.6 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Inspection-and-Comparison">Inspection and Comparison</a> </li> <li> A3.7 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Debugging">Debugging</a> </li> <li> A3.8 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Patching">Patching</a> </li> <li> A3.9 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Email">Email</a> </li> <li> A3.10 <a href="/book/pl/v2/Appendix-C:-Git-Commands-External-Systems">External Systems</a> </li> <li> A3.11 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Administration">Administration</a> </li> <li> A3.12 <a href="/book/pl/v2/Appendix-C:-Git-Commands-Plumbing-Commands">Plumbing Commands</a> </li> </ol> </li> </ol> </div> </div> </div> <span class="light" id="edition"> 2nd Edition </span> </div> <div id="main" data-pagefind-filter="category:book" data-pagefind-meta="category:Book" data-pagefind-weight="0.05" data-pagefind-body class="book edition2"> <h1>5.2 Rozproszony Git - Wgrywanie zmian do projektu</h1> <div> <h2 id="_contributing_project">Wgrywanie zmian do projektu</h2> <div class="paragraph"> <p> Główną trudnością podczas opisywania tego procesu, jest bardzo duża różnorodność sposobów w jaki jest to realizowane. Ponieważ Git jest bardzo elastycznym narzędziem, ludzie mogą i współpracują ze sobą na różne sposoby, dlatego też trudne jest pokazanie w jaki sposób Ty powinieneś – każdy projekt jest inny. Niektóre ze zmiennych które warto wziąć pod uwagę to ilość aktywnych współpracowników, wybrany sposób przepływów pracy, uprawnienia, oraz prawdopodobnie sposób współpracy z zewnętrznymi programistami.</p> </div> <div class="paragraph"> <p>Pierwszą zmienną jest ilość aktywnych współpracowników – ilu aktywnych współpracowników/programistów aktywnie wgrywa zmiany do projektu, oraz jak często? Najczęściej będzie to sytuacja, w której uczestniczy dwóch lub trzech programistów, wgrywających kilka razy na dzień zmiany (lub nawet mniej, przy projektach nie rozwijanych aktywnie). Dla bardzo dużych firm lub projektów, ilość programistów może wynieść nawet tysiące, z dziesiątkami lub nawet setkami zmian wgrywanych każdego dnia. Jest to bardzo ważne, ponieważ przy zwiększającej się liczbie programistów, wypływa coraz więcej problemów podczas włączania efektów ich prac. Zmiany które próbujesz wgrać, mogą stać się nieużyteczne, lub niepotrzebne ze względu na zmiany innych osób z zespołu. Tylko w jaki sposób zachować spójność kodu i poprawność wszystkich przygotowanych łatek?</p> </div> <div class="paragraph"> <p>Następną zmienną jest sposób przepływu pracy w projekcie. Czy jest scentralizowany, w którym każdy programista ma równy dostęp do wgrywania kodu? Czy projekt posiada głównego opiekuna, lub osobę integrującą, która sprawdza wszystkie łatki? Czy wszystkie łatki są wzajemnie zatwierdzane? Czy uczestniczysz w tym procesie? Czy funkcjonuje porucznik, do którego musisz najpierw przekazać swoje zmiany?</p> </div> <div class="paragraph"> <p>Następnym elementem są uprawnienia do repozytorium. Sposób pracy z repozytorium do którego możesz wgrywać zmiany bezpośrednio, jest zupełnie inny, od tego w którym masz dostęp tylko do odczytu. Jeżeli nie masz uprawnień do zapisu, w jaki sposób w projekcie akceptowane są zmiany? Czy ma on określoną politykę? Jak duże zmiany wgrywasz za jednym razem? Jak często je wgrywasz?</p> </div> <div class="paragraph"> <p>Odpowiedzi na wszystkie te pytania, mogą wpływać na to w jaki sposób będziesz wgrywał zmiany do repozytorium, oraz jaki rodzaj przepływu pracy jest najlepszy lub nawet dostępny dla Ciebie. Omówimy aspekty każdej z nich w serii przypadków użycia, przechodząc od prostych do bardziej złożonych; powinieneś móc skonstruować konkretny przepływ pracy który możesz zastosować w praktyce z tych przykładów.</p> </div> <div class="sect3"> <h3 id="_commit_guidelines">Wskazówki wgrywania zmian</h3> <div class="paragraph"> <p>Zanim spojrzysz na poszczególne przypadki użycia, najpierw szybka informacja o treści komentarzy do zmian (<em>commit messages</em>). Dobre wytyczne do tworzenia commitów, oraz związanych z nią treścią komentarzy pozwala na łatwiejszą pracę z Gitem oraz innymi współpracownikami. Projekt Git dostarcza dokumentację która pokazuje kilka dobrych rad dotyczących tworzenia commitów i łat – możesz ją znaleźć w kodzie źródłowym Gita w pliku <code>Documentation/SubmittingPatches</code>.</p> </div> <div class="paragraph"> <p> Po pierwsze, nie chcesz wgrywać żadnych błędów związanych z poprawkami pustych znaków (np. spacji). Git dostarcza łatwy sposób do tego – zanim wgrasz zmiany, uruchom <code>git diff --check</code>, komenda ta pokaże możliwe nadmiarowe spacje.</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/git-diff-check.png" alt="Wynik polecenia `git diff --check`."> </div> <div class="title">Figure 57. Wynik polecenia <code>git diff --check</code>.</div> </div> <div class="paragraph"> <p>Jeżeli uruchomisz tę komendę przed commitem, dowiesz się czy zamierzasz wgrać zmiany które mogą zdenerwować innych programistów.</p> </div> <div class="paragraph"> <p>Następnie spróbuj w każdym commit-ie zawrzeć logicznie odrębny zestaw zmian. Jeżeli możesz, twórz nie za duże łatki – nie programuj cały weekend poprawiając pięć różnych błędów, aby następnie wszystkie je wypuścić w jednym dużym commit-cie w poniedziałek. Nawet jeżeli nie zatwierdzasz zmian w ciągu weekendu, użyj przechowalni ("stage"), aby w poniedziałek rozdzielić zmiany na przynajmniej jeden commit dla każdego błędu, dodając użyteczny komentarz do każdego commitu. Jeżeli niektóre ze zmian modyfikują ten sam plik, spróbuj użyć komendy <code>git add --patch</code>, aby częściowo dodać zmiany do przechowalni (dokładniej opisane to jest w rozdziale <a href="/book/pl/v2/ch00/_interactive_staging">Interaktywne używanie przechowali</a>). Końcowa migawka projektu w gałęzi jest identyczna, nieważne czy zrobisz jeden czy pięć commitów, więc spróbuj ułatwić życie swoim współpracownikom kiedy będą musieli przeglądać Twoje zmiany. Takie podejście ułatwia również pobranie lub przywrócenie pojedynczych zestawów zmian w razie potrzeby. Rozdział <a href="/book/pl/v2/ch00/_rewriting_history">Przepisywanie historii</a> opisuje kilka ciekawych trików dotyczących nadpisywania historii zmian i interaktywnego dodawania plików do przechowalni – używaj ich do utrzymania czystej i przejrzystej historii.</p> </div> <div class="paragraph"> <p>Ostatnią rzeczą na którą należy zwrócić uwagę są komentarze do zmian. Tworzenie dobrych komentarzy pozwala na łatwiejsze używanie i współpracę za pomocą Gita. Generalną zasadą powinno być to, że treść komentarza rozpoczyna się od pojedynczej linii nie dłuższej niż 50 znaków, która zwięźle opisuje zmianę, następnie powinna znaleźć się pusta linia, a poniżej niej szczegółowy opis zmiany. Projekt Git wymaga bardzo dokładnych wyjaśnień motywujących Twoją zmianę w stosunku do poprzedniej implementacji – jest to dobra wskazówka do naśladowania. Dobrym pomysłem jest używania czasu teraźniejszego w trybie rozkazującym. Innymi słowy, używaj komend. Zakładając używanie języka angielskiego w repozytorium, zamiast "I added tests for" lub "Adding tests for", użyj "Add tests for". Poniżej znajduje się szablon komentarza przygotowany przez Tima Pope:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-text" data-lang="text">Krótkie (50 znaków lub mniej) podsumowanie zmian. Bardziej szczegółowy tekst jeżeli jest taka konieczność. Zawijaj wiersze po około 72 znakach. Czasami pierwsza linia jest traktowana jako temat wiadomości email, a reszta komentarza jako treść. Konieczna jest pusta linia oddzielająca podsumowanie od głównej części opisu zmian (chyba że całkowicie pominiesz główną część opisu zmian); narzędzia takie jak `rebase` mogą się pogubić jeśli ich nie oddzielisz. Kolejne paragrafy następują po pustej linii. - wypunktowania są również poprawne, - zazwyczaj myślnik lub gwiazdka jest używana do punktowania, poprzedzona pojedynczym znakiem spacji, z pustą linią pomiędzy, jednak zwyczaje mogą się tutaj różnić.</code></pre> </div> </div> <div class="paragraph"> <p>Jeżeli wszystkie Twoje komentarz do zmian będą wyglądały jak ten, współpraca będzie dużo łatwiejsza dla Ciebie i twoich współpracowników. Projekt Git ma poprawnie sformatowane komentarze, uruchom polecenie <code>git log --no-merges</code> na tym projekcie, aby zobaczyć jak wygląda ładnie sformatowana i prowadzona historia zmian.</p> </div> <div class="paragraph"> <p>W poniższych przykładach, i przez większość tej książki, ze względu na zwięzłość nie sformatowałem treści komentarzy tak ładnie; używam opcji <code>-m</code> do <code>git commit</code>. Rób tak jak mówię, nie tak jak robię.</p> </div> </div> <div class="sect3"> <h3 id="_private_team">Małe prywatne zespoły</h3> <div class="paragraph"> <p> Najprostszym przykładem który możesz spotkać, to prywatne repozytorium z jednym lub dwoma innymi współpracownikami. Jako "prywatne", mamy na myśli repozytorium z zamkniętym kodem źródłowym – niedostępnym do odczytu dla innych. Ty i inny deweloperzy mają uprawniania do wgrywania ("push") swoich zmian.</p> </div> <div class="paragraph"> <p>W takim środowisku możesz naśladować sposób pracy znany z Subversion czy innego scentralizowanego systemu kontroli wersji. Nadal masz wszystkie zalety takie jak commitowanie bez dostępu do centralnego serwera, oraz prostsze tworzenie gałęzi i łączenie zmian, ale przepływ pracy jest bardzo podobny; główną różnicą jest to, że łączenie zmian wykonywane jest po stronie klienta a nie serwera podczas commitu. Zobaczmy jak to może wyglądać, w sytuacji w której dwóch programistów rozpocznie prace z współdzielonym repozytorium. Pierwszy programista, John, klonuje repozytorium, wprowadza zmiany i zatwierdza je lokalnie. (Część komunikatów została zastąpiona znakami <code>...</code> aby skrócić przykłady.)</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Komputer Johna $ git clone john@githost:simplegit.git Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Druga programistka, Jessica, robi to samo – klonuje repozytorium i commituje zmianę:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Komputer Jessiki $ git clone jessica@githost:simplegit.git Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ 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>Następnie, Jessica wypycha swoje zmiany na serwer:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Komputer Jessiki $ git push origin master ... To jessica@githost:simplegit.git 1edee6b..fbff5bc master -> master</code></pre> </div> </div> <div class="paragraph"> <p>John próbuje również wypchnąć swoje zmiany:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Komputer Johna $ 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>John nie może wypchnąć swoich zmian, ponieważ w międzyczasie Jessica wypchnęła swoje. To jest szczególnie ważne do zrozumienia, jeżeli przywykłeś do Subversion, ponieważ zauważysz że każdy z deweloperów zmieniał inne pliki. Chociaż Subversion automatycznie połączy zmiany po stronie serwera jeżeli zmieniane były inne pliki, w Git musisz połączyć zmiany lokalnie. John musi pobrać zmiany Jessiki oraz włączyć je do swojego repozytorium zanim będzie wypychał swoje zmiany:</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>W tym momencie lokalne repozytorium Johna wygląda mniej więcej tak:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/small-team-1.png" alt="Rozbieżna historia w repozytorium Johna."> </div> <div class="title">Figure 58. Rozbieżna historia w repozytorium Johna.</div> </div> <div class="paragraph"> <p>John ma już odniesienie do zmian, które wypchnęła Jessica, ale musi je lokalnie połączyć ze swoimi zmianami, zanim będzie w stanie je wypchnąć:</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 recursive. TODO | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Łączenie zmian poszło bez problemów – historia zmian u Johna wygląda następująco:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/small-team-2.png" alt="Repozytorium Johna po połączeniu z `origin/master`."> </div> <div class="title">Figure 59. Repozytorium Johna po połączeniu z <code>origin/master</code>.</div> </div> <div class="paragraph"> <p>Teraz John może przetestować swój kod tak, aby upewnić się, że nadal działa poprawnie, a następnie wypchnąć swoje zmiany na serwer:</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>Ostatecznie, historia zmian u Johna wygląda tak:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/small-team-3.png" alt="Historia zmian Johna po wypchnięciu ich na serwer `origin`."> </div> <div class="title">Figure 60. Historia zmian Johna po wypchnięciu ich na serwer <code>origin</code>.</div> </div> <div class="paragraph"> <p>W tym samym czasie, Jessica pracowała na swojej tematycznej gałęzi. Stworzyła gałąź <code>issue54</code> oraz wprowadziła trzy zmiany w niej. Nie pobrała jeszcze zmian Johna, więc jej historia zmian wygląda tak:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/small-team-4.png" alt="Gałąź tematyczna Jessiki."> </div> <div class="title">Figure 61. Gałąź tematyczna Jessiki.</div> </div> <div class="paragraph"> <p>Jessica chce zsynchronizować się ze zmianami Johna, więc je pobiera (<code>fetch</code>):</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Komputer Jessiki $ git fetch origin ... From jessica@githost:simplegit fbff5bc..72bbc59 master -> origin/master</code></pre> </div> </div> <div class="paragraph"> <p>Ta komenda pobiera zmiany Johna, które wprowadził w międzyczasie. Historia zmian u Jessiki wygląda następująco:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/small-team-5.png" alt="Historia zmian u Jessiki po pobraniu zmian Johna."> </div> <div class="title">Figure 62. Historia zmian u Jessiki po pobraniu zmian Johna.</div> </div> <div class="paragraph"> <p>Jessica uważa swoje prace w tej gałęzi za zakończone, ale chciałaby wiedzieć jakie zmiany musi włączyć aby mogła wypchnąć swoje. Uruchamia komendę <code>git log</code> aby się tego dowiedzieć:</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>Składnia <code>issue54..origin/master</code> jest filtrem logu, który prosi Gita o pokazanie tylko listy commitów, które są na drugiej gałęzi (w tym przypadku <code>origin/master</code>), które nie są na pierwszej gałęzi (w tym przypadku <code>issue54</code>). Omówimy tę składnię szczegółowo w <a href="/book/pl/v2/ch00/_commit_ranges">Zakresy zmian</a>.</p> </div> <div class="paragraph"> <p>Na razie widzimy w wyniku powyższego polecenia, że jest jeden commit Johna, którego nie scaliła Jessicą. Jeśli dołączy ona zmiany z <code>origin/master</code>, to będzie to pojedynczy commit, który zmodyfikuje jej lokalną pracę.</p> </div> <div class="paragraph"> <p>Teraz Jessica może połączyć swoje zmiany tematyczne do swojej głównej gałęzi <code>master</code>, włączyć zmiany Johna (<code>origin/master</code>) do swojej gałęzi <code>master</code>, a następnie wypchnąć zmiany ponownie na serwer. Najpierw przełącza się z powrotem do swojej głównej gałęzi <code>master</code>, tak aby zintegrować całą tę pracę:</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>Jako pierwszą gałąź może ona włączyć zarówno <code>origin/master</code> jak i <code>issue54</code> – obie są nadrzędne więc kolejność nie ma znaczenia. Końcowa wersja plików powinna być identyczna bez względu na wybraną kolejność; tylko historia będzie się lekko różniła. Jako pierwszą gałąź do włączenia Jessica wybiera <code>issue54</code>:</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>Nie było problemów; jak widzisz był to proste połączenie tzw. <em>fast-forward</em>. Teraz Jessica może włączyć zmiany Johna (<code>origin/master</code>):</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 recursive. lib/simplegit.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Wszystko połączyło się bez problemów, więc historia zmian u Jessiki wygląda następująco:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/small-team-6.png" alt="Historia zmian u Jessiki po włączeniu zmian Johna."> </div> <div class="title">Figure 63. Historia zmian u Jessiki po włączeniu zmian Johna.</div> </div> <div class="paragraph"> <p>Teraz <code>origin/master</code> jest dostępny z gałęzi <code>master</code> u Jessiki, więc powinna bez problemów móc wypchnąć swoje zmiany (zakładając że w międzyczasie John niczego nie wypchnął):</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>Każdy programista wprowadził zmiany kilkukrotnie, oraz połączył zmiany drugiego bez problemów.</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/small-team-7.png" alt="Historia zmian u Jessiki po wypchnięciu zmian na serwer."> </div> <div class="title">Figure 64. Historia zmian u Jessiki po wypchnięciu zmian na serwer.</div> </div> <div class="paragraph"> <p>Jest to jeden z najprostszych przepływów pracy. Pracujesz przez chwilę, generalnie na tematycznych gałęziach i włączasz je do gałęzi <code>master</code> kiedy są gotowe. Kiedy chcesz podzielić się swoją pracą, włączasz je do swojej gałęzi <code>master</code>, pobierasz i włączasz zmiany z <code>origin/master</code> jeżeli jakieś były, a następnie wypychasz gałąź <code>master</code> na serwer. Zazwyczaj sekwencja będzie wyglądała mniej więcej tak:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/small-team-flow.png" alt="Sekwencja zdarzeń dla prostego przepływu zmian między programistami."> </div> <div class="title">Figure 65. Sekwencja zdarzeń dla prostego przepływu zmian między programistami.</div> </div> </div> <div class="sect3"> <h3 id="_prywatne_zarządzane_zespoły">Prywatne zarządzane zespoły</h3> <div class="paragraph"> <p> W tym scenariuszu, zobaczysz jak działa współpraca w większych prywatnych grupach. Nauczysz się jak pracować w środowisku w którym małe grupy współpracują ze sobą nad funkcjonalnościami, a następnie stworzone przez nich zmiany są integrowane przez inną osobę.</p> </div> <div class="paragraph"> <p>Załóżmy że John i Jessica wspólnie pracują nad jedną funkcjonalnością, a Jessica i Josie nad drugą. W tej sytuacji, organizacja używa przepływu pracy z osobą integrującą zmiany, w której wyniki pracy poszczególnych grup są integrowane przez wyznaczone osoby, a gałąź <code>master</code> może być jedynie przez nie aktualizowana W tym scenariuszu, cała praca wykonywana jest w osobnych gałęziach zespołów, a następnie zaciągana przez osoby integrujące.</p> </div> <div class="paragraph"> <p>Prześledźmy sposób pracy Jessiki w czasie gdy pracuje ona nad obiema funkcjonalnościami, współpracując jednocześnie z dwoma niezależnymi programistami. Zakładając że ma już sklonowane repozytorium, rozpoczyna pracę nad funkcjonalnością <code>featureA</code>. Tworzy dla niej nową gałąź i wprowadza w niej zmiany:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Komputer Jessiki $ 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>Teraz musi podzielić się swoją pracą z Johnem, więc wypycha zmiany z gałęzi <code>featureA</code> na serwer. Jessica nie ma uprawnień do zapisywania w gałęzi <code>master</code> – tylko osoby integrujące je mają – więc musi wysłać osobną gałąź aby współpracować z Johnem:</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 powiadamia Johna e-mailem, że wysłała swoje zmiany w gałęzi <code>featureA</code> i może je on zweryfikować. W czasie gdy czeka na informację zwrotną od Johna, Jessica rozpoczyna pracę nad <code>featureB</code> z Josie. Na początku, tworzy nową gałąź przeznaczoną dla nowej funkcjonalności, podając jako gałąź źródłową gałąź <code>master</code> na serwerze:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console"># Komputer Jessiki $ git fetch origin $ git checkout -b featureB origin/master Switched to a new branch 'featureB'</code></pre> </div> </div> <div class="paragraph"> <p>Następnie, Jessica wprowadza kilka zmian i zapisuje je w gałęzi <code>featureB</code>:</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>Repozytorium Jessiki wygląda następująco:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/managed-team-1.png" alt="Początkowa historia zmian u Jessiki."> </div> <div class="title">Figure 66. Początkowa historia zmian u Jessiki.</div> </div> <div class="paragraph"> <p>Jest gotowa do wypchnięcia swoich zmian, ale dostaje wiadomość e-mail od Josie, że gałąź z pierwszymi zmianami została już udostępniona na serwerze jako <code>featureBee</code>. Jessica najpierw musi połączyć te zmiany ze swoimi, zanim będzie mogła wysłać je na serwer. Może więc pobrać zmiany Josie za pomocą komendy <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>Jessica może teraz połączyć zmiany ze swoimi za pomocą <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 recursive. lib/simplegit.rb | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)</code></pre> </div> </div> <div class="paragraph"> <p>Powstał drobny problem – musi wysłać połączone zmiany ze swojej gałęzi <code>featureB</code> do <code>featureBee</code> na serwerze. Może to zrobić poprzez wskazanie lokalnej i zdalnej gałęzi oddzielonej dwukropkiem (:), jako parametr do komendy <code>git push</code>:</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>Jest to nazywane <em>refspec</em>. Zobacz sekcję <a href="/book/pl/v2/ch00/_refspec">Refspec</a> aby dowiedzieć się więcej o <em>refspec</em> i o rzeczach, które można z nimi zrobić. Zwróć uwagę również na flagę <code>-u</code>; jest to skrót od flagi <code>--set-upstream</code>, która konfiguruje gałęzie aby później łatwiej wypychało się pobierało zmiany.</p> </div> <div class="paragraph"> <p>Następnie John wysyła e-mail do Jessiki z informacją, że wgrał swoje zmiany do gałęzi <code>featureA</code> i prosi ją o ich weryfikację. Uruchamia więc ona <code>git fetch</code> aby pobrać te zmiany:</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>Następnie za pomocą komendy <code>git log</code> może ona zobaczyć co zostało zmienione:</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>Ostatecznie, integruje ona zmiany Johna ze swoimi znajdującymi się w gałęzi <code>featureA</code>:</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 postanawia jednak jeszcze coś poprawić, więc commituje ponownie i wysyła zmiany z powrotem na serwer:</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>Historia zmian u Jessiki wygląda teraz mniej więcej tak:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/managed-team-2.png" alt="Historia zmian u Jessiki po wprowadzeniu zmian w gałęzi."> </div> <div class="title">Figure 67. Historia zmian u Jessiki po wprowadzeniu zmian w gałęzi.</div> </div> <div class="paragraph"> <p>Jessica, Josie i John powiadamiają osoby zajmujące się integracją, że gałęzie <code>featureA</code> i <code>featureBee</code> na serwerze są gotowe do integracji z głównym kodem. Po włączeniu tych gałęzi do głównej, zostaną pobrane zmiany, tworząc historię zmian podobną do poniższej:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/managed-team-3.png" alt="Historia zmian u Jessiki po włączeniu jej obu gałęzi."> </div> <div class="title">Figure 68. Historia zmian u Jessiki po włączeniu jej obu gałęzi.</div> </div> <div class="paragraph"> <p>Wiele osób przechodzi na Gita ze względu na możliwość jednoczesnej współpracy kilku zespołów, oraz możliwości włączania efektów ich prac w późniejszym terminie. Możliwość tworzenie małych, współpracujących ze sobą grup przy pomocy zdalnych gałęzi bez konieczności angażowania pozostałych członków zespołu, jest bardzo dużą zaletą Gita. Sekwencja przepływu pracy, którą tutaj zobaczyłeś, jest podobna do poniższej:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/managed-team-flow.png" alt="Podstawowa sekwencja omawianego przepływu pracy w zespole zarządzanym."> </div> <div class="title">Figure 69. Podstawowa sekwencja omawianego przepływu pracy w zespole zarządzanym.</div> </div> </div> <div class="sect3"> <h3 id="_public_project">Sforkowany publiczny projekt</h3> <div class="paragraph"> <p> Współpraca przy projektach publicznych jest trochę inne. Ponieważ nie masz uprawnień do bezpośredniego wgrywania zmian w projekcie, musisz przekazać swoje zmiany do opiekunów w inny sposób. Pierwszy przykład opisuje udział w projekcie poprzez rozwidlenie (fork) w serwisie, który to umożliwia. Wiele serwisów hostingowych udostępnia taką możliwość (w tym GitHub, BitBucket, Google Code, repo.or.cz i inne), a wielu opiekunów projektów oczekuje takiego stylu współpracy. Następna sekcja opisuje współpracę w projektach, które preferują otrzymywanie poprawek poprzez e-mail.</p> </div> <div class="paragraph"> <p>Po pierwsze, na początku musisz sklonować główne repozytorium, stworzyć gałąź tematyczną dla zmian które planujesz wprowadzić oraz dokonać tam zmian. Sekwencja komend wygląda następująco:</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 # (zmiany) $ git commit # (zmiany) $ git commit</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content"> <div class="paragraph"> <p>Możesz chcieć użyć <code>rebase -i</code>, aby złączyć swoje zmiany do jednego commita, lub przeorganizować je, tak aby poprawka była łatwiejsza do zweryfikowania przez opiekuna - zobacz sekcję <a href="/book/pl/v2/ch00/_rewriting_history">Przepisywanie historii</a>, aby dowiedzieć się więcej o tego typu operacjach.</p> </div> </td> </tr> </table> </div> <div class="paragraph"> <p>Kiedy zmiany w Twojej gałęzi zostaną zakończone i jesteś gotowy do przekazania ich do opiekunów projektu, wejdź na stronę projektu i kliknij przycisk "Fork", tworząc w ten sposób swoją własną kopię projektu z uprawnieniami do zapisu. Następnie musisz dodać nowy URL do repozytorium jako drugie repozytorium zdalne, w tym przypadku nazwane <code>myfork</code>:</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>Musisz teraz wysłać do niego swoje zmiany. Najprościej będzie wypchnąć gałąź tematyczną, na której pracujesz, do zdalnego repozytorium, zamiast włączać zmiany do Twojej gałęzi <code>master</code> i dopiero potem je wysyłać. Warto zrobić tak dlatego, że w sytuacji, w której Twoje zmiany nie zostaną zaakceptowane lub zostaną zaakceptowane tylko częściowo, nie będziesz musiał cofać swojej gałęzi <code>master</code>. Jeżeli opiekun włączy, zmieni bazę lub pobierze część Twoich zmian, będziesz mógł je otrzymać zaciągając je z ich repozytorium:</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> Kiedy wgrasz wprowadzone zmiany do swojego rozwidlenia projektu, powinieneś powiadomić o tym opiekuna. Jest to często nazywane operacją <em>pull request</em> i możesz ją wykonać albo poprzez stronę internetową – GitHub ma własny mechanizm "Pull Request", który omówimy w rodziale <a href="/book/pl/v2/ch00/_github">GitHub</a> – albo wykonując komendę <code>git request-pull</code> i ręcznie wysyłając jej wynik e-mailem do opiekuna projektu.</p> </div> <div class="paragraph"> <p>Komenda <code>request-pull</code> pobiera docelową gałąź, do której chcesz wysłać zmiany, oraz adres URL repozytorium Gita, z którego chcesz pobrać zmiany, a następnie generuje podsumowanie zmian, które będziesz wysyłał. Na przykład, jeżeli Jessica chce wysłać do Johna <em>pull request</em>, a wykonała dwie zmiany na swojej gałęzi tematycznej, którą właśnie wypchnęła, to może wydać poniższe polecenia:</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: John 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>Wynik tej komendy może być wysłany do opiekuna – mówi on z której gałęzi pochodzą zmiany, podsumowuje commity, oraz pokazuje skąd można je pobrać.</p> </div> <div class="paragraph"> <p>W projekcie w którym nie jesteś opiekunem, najprostszym sposobem jest utrzymywanie gałęzi <code>master</code> która śledzi <code>origin/master</code>, a wprowadzać zmiany w tematycznych gałęziach, które możesz łatwo usunąć jeżeli zostaną odrzucone. Posiadanie oddzielnych gałęzi dla różnych funkcjonalności, ułatwia również Tobie zmianę bazy ("rebase") jeżeli główna gałąź zostanie zmieniona i przygotowana poprawka nie może się poprawnie nałożyć. Na przykład, jeżeli chcesz wysłać drugi zestaw zmian do projektu, nie kontynuuj pracy na gałęzi którą właśnie wypchnąłeś – rozpocznij nową z gałąź <code>master</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git checkout -b featureB origin/master # (zmiany) $ git commit $ git push myfork featureB # (e-mail do opiekuna) $ git fetch origin</code></pre> </div> </div> <div class="paragraph"> <p>Teraz, każdy z zestawów zmian przechowywany jest w formie silosu – podobnego do kolejki z poprawkami – które możesz nadpisać, zmienić, bez konieczności nachodzenia na siebie, tak jak przedstawiono to poniżej:</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/public-small-1.png" alt="Początkowa historia zmian z poprawkami z gałęzi `featureB`."> </div> <div class="title">Figure 70. Początkowa historia zmian z poprawkami z gałęzi <code>featureB</code>.</div> </div> <div class="paragraph"> <p>Załóżmy, że opiekun projektu pobrał Twoje zmiany i sprawdził Twoją pierwszą gałąź, ale niestety nie łączy się ona bez przeszkód. W takiej sytuacji, możesz spróbować wykonać <code>rebase</code> na gałęzi <code>origin/master</code>, rozwiązać konflikty i ponownie wysłać zmiany:</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>Przepisuje to Twoją historię zmian, która wygląda teraz tak:</p> </div> <div id="psp_b" class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/public-small-2.png" alt="Historia zmian po pracach na gałęzi `featureA`."> </div> <div class="title">Figure 71. Historia zmian po pracach na gałęzi <code>featureA</code>.</div> </div> <div class="paragraph"> <p>Z powodu zmiany bazy (<code>rebase</code>) na gałęzi, musisz użyć przełącznika <code>-f</code> do komendy <code>push</code>, tak abyś na serwerze mógł nadpisać gałąź <code>featureA</code> commitem, który nie jest jej potomkiem. Alternatywą może być wysłanie tych zmian do nowej gałęzi na serwerze (np. nazwanej <code>featureAv2</code>).</p> </div> <div class="paragraph"> <p>Spójrzmy na jeszcze jeden scenariusz. Opiekun spojrzał na zmiany w Twojej drugiej gałęzi i spodobał mu się pomysł, ale chciałby abyś zmienił sposób w jaki je zaimplementowałeś. Skorzystasz również z okazji, aby przenieść pracę na aktualną gałąź <code>master</code> projektu. Tworzysz więc nową gałąź bazując na <code>origin/master</code>, złączasz tam zmiany z gałęzi <code>featureB</code>, rozwiązujesz ewentualne konflikty, wprowadzasz zmiany w implementacji i następnie wypychasz zmiany do nowej gałęzi:</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 # (zmiany w implementacji) $ git commit $ git push myfork featureBv2</code></pre> </div> </div> <div class="paragraph"> <p>Opcja <code>--squash</code> bierze całą pracę wykonaną w połączonej gałęzi i łączy ją w jeden zestaw zmian, tworząc stan repozytorium tak jakby nastąpiło prawdziwe scalenie, bez faktycznego wykonywania commitu scalającego. Oznacza to, że Twój przyszły commit będzie miał tylko jednego rodzica i pozwala na wprowadzenie wszystkich zmian z innej gałęzi, a następnie dokonanie kolejnych zmian przed zarejestrowaniem nowego commitu. Również opcja <code>--no-commit</code> może być przydatna do opóźnienia commitu scalającego w przypadku domyślnego procesu scalania.</p> </div> <div class="paragraph"> <p>Teraz możesz wysłać do opiekuna wiadomość, że wprowadziłeś wszystkie wymagane zmiany, które może znaleźć w gałęzi <code>featureBv2</code>.</p> </div> <div class="imageblock"> <div class="content"> <img src="/book/pl/v2/images/public-small-3.png" alt="Historia zmian po zmianach w gałęzi `featureBv2`."> </div> <div class="title">Figure 72. Historia zmian po zmianach w gałęzi <code>featureBv2</code>.</div> </div> </div> <div class="sect3"> <h3 id="_project_over_email">Publiczne projekty poprzez e-mail</h3> <div class="paragraph"> <p> Duża ilość większych projektów ma ustalone reguły dotyczące akceptowania poprawek – będziesz musiał sprawdzić konkretne zasady dla każdego z projektów, ponieważ będą się różniły. Jednak sporo większych projektów akceptuje poprawki poprzez listy mailingowe przeznaczone dla programistów, dlatego też teraz opiszemy ten przykład.</p> </div> <div class="paragraph"> <p>Przepływ pracy jest podobny do poprzedniego – tworzysz tematyczne gałęzie dla każdej grupy zmian, nad którymi pracujesz. Różnica polega na tym, w jaki sposób wysyłasz je do projektu. Zamiast tworzyć rozwidlenie (<em>fork</em>) i wypychać do niego zmiany, tworzysz wiadomość e-mail dla każdego zestawu zmian i wysyłasz je na listę mailingową:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code class="language-console" data-lang="console">$ git checkout -b topicA # (zmiany) $ git commit # (zmiany) $ git commit</code></pre> </div> </div> <div class="paragraph"> <p> Teraz masz dwa commity, które chcesz wysłać na listę dyskusyjną. Użyj <code>git format-patch</code> do wygenerowania plików w formacie <em>mbox</em>, które możesz wysłać na listę – zamieni to każdy commit w osobną wiadomość, z pierwszą linią komentarza ("commit message") jako tematem, jego pozostałą częścią w treści, dołączając jednocześnie zawartość wprowadzanej zmiany. Miłą rzeczą jest to, że aplikowanie poprawki przesłanej przez e-mail i wygenerowanej za pomocą <code>format-patch</code> zachowuje wszystkie informacje o commicie.</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>Komenda <code>format-patch</code> wypisuje nazwy plików, które stworzyła. Opcja <code>-M</code> mówi Git, aby brał pod uwagę również zmiany nazw plików. Zawartość plików w efekcie końcowym wygląda tak:</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>Możesz oczywiście zmienić te pliki i dodać większą ilość informacji w mailu, których nie chciałeś pokazywać w komentarzu do zmiany. Jeżeli dodasz tekst miedzy linię <code>---</code> a początkiem poprawki (linia <code>diff --git</code>), programiści będą mogli to przeczytać, ale wdrażanie poprawki pominie te fragmenty.</p> </div> <div class="paragraph"> <p>Aby wysłać to na listę mailingową, możesz albo wkleić zawartość plików w programie e-mail lub użyć programu uruchamianego z linii komend. Wklejanie tekstu często wprowadza problemy z zachowaniem formatowania, szczególnie przy użyciu tych "mądrzejszych" programów pocztowych, które nie zachowują poprawnie znaków nowej linii i spacji. Na szczęście Git udostępnia narzędzie, które pomoże Ci wysłać poprawnie sformatowane poprawki poprzez protokół IMAP, może to być łatwiejsze dla Ciebie. Pokażemy w jaki sposób wysyłać poprawki przy pomocy Gmaila, który tak się składa, że jest agentem poczty elektronicznej, którego znamy najlepiej. Możesz znaleźć bardziej szczegółowe instrukcje dla różnych programów pocztowych na końcu wcześniej wymienionego pliku <code>Documentation/SubmittingPatches</code>, który znajduje się w kodzie źródłowym Gita.</p> </div> <div class="paragraph"> <p> Najpierw musisz ustawić sekcję <code>imap`</code> w swoim pliku <code>~/.gitconfig</code>. Możesz ustawić każdą wartość oddzielnie przy pomocy kilku komend <code>git config</code> lub możesz je dodać ręcznie, jednak w efekcie Twój plik konfiguracyjny powinien wyglądać podobnie do poniższego:</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 = p4ssw0rd port = 993 sslverify = false</code></pre> </div> </div> <div class="paragraph"> <p>Jeżeli Twój serwer IMAP nie używa SSL, to dwie ostatnie linie prawdopodobnie nie są potrzebne, a w polu <code>host</code> będzie <code>imap://</code> zamiast <code>imaps://</code>. Po takiej konfiguracji możesz używać komendy <code>git imap-send</code> aby umieścić poprawki w folderze "Wersje robocze" ("Draft") na podanym serwerze IMAP:</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>W tym momencie powinieneś być w stanie przejść do swojego folderu "Wersje robocze", zmienić pole "Do" ("To") na listę mailingową, na którą wysyłasz poprawkę, ewentualnie dodać w "DW" ("Do wiadomości", ang. "CC" czyli "Carbon Copy") adres e-mail opiekuna lub osoby odpowiedzialnej za daną sekcję, i ostatecznie wysłać e-maila.</p> </div> <div class="paragraph"> <p>Możesz także wysyłać poprawki przez serwer SMTP. Tak jak poprzednio, możesz ustawić każdą wartość osobno za pomocą serii komend <code>git config</code> lub możesz dodać je ręcznie w sekcji <code>sendemail</code> w swoim pliku <code>~/.gitconfig</code>:</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>Po wykonaniu tych czynności, możesz użyć komendy <code>git send-email</code> do wysłania swoich poprawek:</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>Następnie Git wyświetla dla każdej wysyłanej poprawki kilka informacji, które wyglądają mniej więcej tak:</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="_podsumowanie_5">Podsumowanie</h3> <div class="paragraph"> <p>Powyższa sekcja opisywała kilka z najczęściej używanych sposobów przepływu pracy z różnymi projektami Git, które możesz spotkać, oraz wprowadziła kilka nowych narzędzi ułatwiajacych ten proces. W następnych sekcjach zobaczysz jak wygląda praca nad projektem, ale z drugiej strony: będzie to utrzymywanie projektu Git. Nauczysz się jak być miłosiernym dyktatorem oraz osobą integrującą zmiany innych osób.</p> </div> </div> <div id="nav"><a href="/book/pl/v2/Rozproszony-Git-Rozproszone-przepływy-pracy">prev</a> | <a href="/book/pl/v2/Rozproszony-Git-Utrzymywanie-projektu">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>