diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..67cb06e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*~ +_site/ +*.swp +.DS_Store diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..af94b35 --- /dev/null +++ b/.htaccess @@ -0,0 +1,27 @@ +Redirect permanent /2009/01/27/installing-git.html /beginner/2009/01/27/installing-git.html +Redirect permanent /2009/01/25/branching-and-merging.html /beginner/2009/01/25/branching-and-merging.html +Redirect permanent /2009/01/27/installing-git.html /beginner/2009/01/27/installing-git.html +Redirect permanent /2009/01/25/branching-and-merging.html /beginner/2009/01/25/branching-and-merging.html +Redirect permanent /2009/01/21/pushing-and-pulling.html /beginner/2009/01/21/pushing-and-pulling.html +Redirect permanent /2009/01/19/ignoring-files.html /beginner/2009/01/19/ignoring-files.html +Redirect permanent /2009/01/18/the-staging-area.html /beginner/2009/01/18/the-staging-area.html +Redirect permanent /2009/01/16/cleaning-up-untracked-files.html /beginner/2009/01/16/cleaning-up-untracked-files.html +Redirect permanent /2009/01/11/reverting-files.html /beginner/2009/01/11/reverting-files.html +Redirect permanent /2009/01/10/stashing-your-changes.html /beginner/2009/01/10/stashing-your-changes.html +Redirect permanent /2009/01/26/text-based-graph.html /intermediate/2009/01/26/text-based-graph.html +Redirect permanent /2009/01/24/sharing-your-changes.html /intermediate/2009/01/24/sharing-your-changes.html +Redirect permanent /2009/01/22/count-your-commits.html /intermediate/2009/01/22/count-your-commits.html +Redirect permanent /2009/01/26/text-based-graph.html /intermediate/2009/01/26/text-based-graph.html +Redirect permanent /2009/01/24/sharing-your-changes.html /intermediate/2009/01/24/sharing-your-changes.html +Redirect permanent /2009/01/22/count-your-commits.html /intermediate/2009/01/22/count-your-commits.html +Redirect permanent /2009/01/14/interactive-adding.html /intermediate/2009/01/14/interactive-adding.html +Redirect permanent /2009/01/13/visualizing-your-repo.html /intermediate/2009/01/13/visualizing-your-repo.html +Redirect permanent /2009/01/09/checkout-remote-tracked-branch.html /intermediate/2009/01/09/checkout-remote-tracked-branch.html +Redirect permanent /2009/01/28/zsh-git-status.html /advanced/2009/01/28/zsh-git-status.html +Redirect permanent /2009/01/23/bash-git-status.html /advanced/2009/01/23/bash-git-status.html +Redirect permanent /2009/01/28/zsh-git-status.html /advanced/2009/01/28/zsh-git-status.html +Redirect permanent /2009/01/23/bash-git-status.html /advanced/2009/01/23/bash-git-status.html +Redirect permanent /2009/01/20/bend-logs-to-your-will.html /advanced/2009/01/20/bend-logs-to-your-will.html +Redirect permanent /2009/01/17/restoring-lost-commits.html /advanced/2009/01/17/restoring-lost-commits.html +Redirect permanent /2009/01/15/piecemeal-staging.html /advanced/2009/01/15/piecemeal-staging.html +Redirect permanent /2009/01/12/fixing-broken-commit-messages.html /advanced/2009/01/12/fixing-broken-commit-messages.html diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..c86f690 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,21 @@ +Git Ready has been translated into several languages thanks to many +awesome contributors. If you've translated an article or contributed in some +way, please add your name in here. Thanks! + +English +======= + +Nick Quaranto + +Portuguese +========== + +Tailor R. Fontela +Marcio Trindade +Willian Molinari +Felipe Coury + +German +====== + +Nico Gulden diff --git a/CC-LICENSE b/CC-LICENSE new file mode 100644 index 0000000..122e35e --- /dev/null +++ b/CC-LICENSE @@ -0,0 +1,59 @@ +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + +1. Definitions + + 1. "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with one or more other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License. + 2. "Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of derivatives of works made available under that license under this License or either a Creative Commons unported license or a Creative Commons jurisdiction license with the same License Elements as this License. + 3. "Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License. + 4. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike. + 5. "Licensor" means the individual, individuals, entity or entities that offers the Work under the terms of this License. + 6. "Original Author" means the individual, individuals, entity or entities who created the Work. + 7. "Work" means the copyrightable work of authorship offered under the terms of this License. + 8. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. + +2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: + + 1. to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works; + 2. to create and reproduce Derivative Works provided that any such Derivative Work, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; + 3. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works; + 4. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission Derivative Works. + 5. + + For the avoidance of doubt, where the Work is a musical composition: + 1. Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to collect, whether individually or, in the event that Licensor is a member of a performance rights society (e.g. ASCAP, BMI, SESAC), via that society, royalties for the public performance or public digital performance (e.g. webcast) of the Work. + 2. Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to collect, whether individually or via a music rights agency or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions). + 6. Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a sound recording, Licensor waives the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions). + +The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved. + +4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + + 1. You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of a recipient of the Work to exercise of the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. When You distribute, publicly display, publicly perform, or publicly digitally perform the Work, You may not impose any technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise of the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any credit as required by Section 4(c), as requested. If You create a Derivative Work, upon notice from any Licensor You must, to the extent practicable, remove from the Derivative Work any credit as required by Section 4(c), as requested. + 2. You may distribute, publicly display, publicly perform, or publicly digitally perform a Derivative Work only under: (i) the terms of this License; (ii) a later version of this License with the same License Elements as this License; (iii) either the Creative Commons (Unported) license or a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g. Attribution-ShareAlike 3.0 (Unported)); (iv) a Creative Commons Compatible License. If you license the Derivative Work under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Derivative Work under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and with the following provisions: (I) You must include a copy of, or the Uniform Resource Identifier for, the Applicable License with every copy or phonorecord of each Derivative Work You distribute, publicly display, publicly perform, or publicly digitally perform; (II) You may not offer or impose any terms on the Derivative Works that restrict the terms of the Applicable License or the ability of a recipient of the Work to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties; and, (IV) when You distribute, publicly display, publicly perform, or publicly digitally perform the Work, You may not impose any technological measures on the Derivative Work that restrict the ability of a recipient of the Derivative Work from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Derivative Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Derivative Work itself to be made subject to the terms of the Applicable License. + 3. If You distribute, publicly display, publicly perform, or publicly digitally perform the Work (as defined in Section 1 above) or any Derivative Works (as defined in Section 1 above) or Collective Works (as defined in Section 1 above), You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or (ii) if the Original Author and/or Licensor designate another party or parties (e.g. a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; the title of the Work if supplied; to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and, consistent with Section 3(b) in the case of a Derivative Work, a credit identifying the use of the Work in the Derivative Work (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Derivative Work or Collective Work, at a minimum such credit will appear, if a credit for all contributing authors of the Derivative Work or Collective Work appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND ONLY TO THE EXTENT OF ANY RIGHTS HELD IN THE LICENSED WORK BY THE LICENSOR. THE LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MARKETABILITY, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + 1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Derivative Works or Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. + 2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. + +8. Miscellaneous + + 1. Each time You distribute or publicly digitally perform the Work (as defined in Section 1 above) or a Collective Work (as defined in Section 1 above), the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. + 2. Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. + 3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + 4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. + 5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. + diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..717481e --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +de.gitready.com diff --git a/MIT-LICENSE b/MIT-LICENSE new file mode 100644 index 0000000..2071a36 --- /dev/null +++ b/MIT-LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2009, Nick Quaranto + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/README b/README deleted file mode 100644 index 46cbe2d..0000000 --- a/README +++ /dev/null @@ -1,5 +0,0 @@ -Hi there! - -The official repo for gitready has moved to http://github.com/gitready/gitready since we're moving onto GitHub pages. - -Please update your remotes! And if you want commit access to maintain your language's translations, or to write new articles, bug @qrush! diff --git a/README.md b/README.md new file mode 100644 index 0000000..464a07f --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# Git Ready + +> There is only one way to *get ready* for immortality, and that is to love this life and live it as bravely and faithfully and cheerfully as we can.
+> ~ Henry Van Dyke + +## Über + +Dieses Repository beinhaltet HTML, CSS, Bilder und Beitrage für [gitready.com](http://gitready.com). Git Ready (war täglich, dann drei-wöchentlich, und jetzt) wöchentlich Tips für jene, die mehr über dieses verteilte Versionskontrollsystem lernen möchten oder gerade damit angefangen haben. Dieses Blog als Ganzes startete als Reise, um mehr über Git zu lernen und Anderen seine Nützlichkeit zu zeigen. Wenn du eine Frage zum Inhalt hast, schicke [qrush eine Nachricht auf GitHub](http://github.com/qrush) oder schreibe eine E-Mail an [nick@quaran.to](mailto://nick@quaran.to). + +## Veröffentlichen + +Das Blog wird mit der [Jekyll](http://github.com/mojombo/jekyll) Engine erzeugt. Die Formatierung orientiert sich an den Grundlagen, auch das statische HTML. Sorgen zur Skalierbarkeit existieren nicht. + +## Mitmachen + +Wenn du Ideen zu neuen Seiten, Layouts oder irgendetwas hast, spalte ab (fork)!
Wenn du Tips einreichen möchtest, [mache das hier](http://gitready.com/submit.html). + +## Übersetzung + +Wenn du daran interessiert bist, Beiträge in deine Sprache zu übersetzen, großartig! Hier eine kurze Anleitung: + +* Spalte das Projekt ab (fork). +* Erzeuge einen Zweig mit dem ISO Code für deine Sprache, für Englisch: + +
+git checkout -b en
+
+ +* Markiere alle Beiträge als unveröffentlicht und übergebe deine Änderungen: + +
+rake unpublish
+git commit -am "Unpublishing all the posts"
+
+ +* Übersetze die Kopf- und Fußzeilen der Startseite. Schau dir die anderen übersetzen Seiten als Beispiele an, wie die [deutsche Seite](http://de.gitready.com). +* Übersetze so wenige oder so viele Beiträge, wie du möchtest. +* Lade deine Arbeit hoch (push) und vergiß nicht den richtigen Zweig zu verwenden!: + +
+git push origin en
+
+ +* Reiche alle Pull-Anfragen an qrushs Repository. + +Sobald das erledigt ist, füge ich die Subdomain deiner Sprache hinzu und veröffentliche deine Arbeit. + +## Lizensierung + +Der tatsächliche Inhalt der Artikel ist unter der Creative Commons lizensiert. Der Quellcode, der dieses Projekt erzeugt, ist unter MIT lizensiert. + +Grundsätzlich, wenn du die Blogbeiträge weiter verteilen möchtest, stelle die Rückverlinkung sicher. Wenn du den Inhalt veröffentlichen möchtest, ist das auch in Ordnung, behalte bitte die Lizenzinformationen bei. diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..e36bb81 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +auto: false diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 0000000..80c3593 --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,103 @@ + + + + + + git ready » {{ page.title }} + + + + + + + +
+
+

git ready

+
+
+
Lerne Git Commit für Commit
+
von Nick Quaranto, Übersetzung von Nico Gulden
+
+
+ {{ content }} +
+ + + + + +
+ + +
+ +
+ + diff --git a/_layouts/post.html b/_layouts/post.html new file mode 100644 index 0000000..4c11f7e --- /dev/null +++ b/_layouts/post.html @@ -0,0 +1,14 @@ +--- +layout: default +--- +
+

+ {{ page.title }} +

+
eingetragen am {{ page.date | date_to_string }}
+ {{ content }} + +
+ diff --git a/_posts/2009-01-09-checkout-remote-tracked-branch.textile b/_posts/2009-01-09-checkout-remote-tracked-branch.textile new file mode 100644 index 0000000..6499f59 --- /dev/null +++ b/_posts/2009-01-09-checkout-remote-tracked-branch.textile @@ -0,0 +1,37 @@ +--- +layout: post +title: Einen entfernten, verfolgen Zweig auschecken +category: intermediate +--- + +Die folgenden Schritte führe ich regelmäßig durch, wenn ich meine zahlreichen Computer aufsetze oder synchronisiere und jedesmal scheine ich die Kommandos dafür zu vergessen. So laß uns annehmen, dass du mehr als einen Zweig in deinem entfernten Repository hast und du möchtest ihn auch in dein lokales Repository einbringen: + +p=. !http://gitready.com/images/branches.png! + +Das Anzeigen von Informationen in einem entfernten Repository sieht in etwa wie folgt aus: + +
+$ git remote show origin
+  * remote origin
+    URL: *************
+    Remote branch merged with 'git pull' 
+      while on branch master
+        master
+      Tracked remote branches
+        haml master
+
+ +Glücklicherweise ist die Kommandosyntax hierfür recht einfach: + +
+git checkout --track -b 
+   /
+
+ +In meinem Fall benutze ich das Kommando: + +@git checkout --track -b haml origin/haml@ + +Du kannst auch eine einfacherer Variante verwenden: + +@git checkout -t origin/haml@ diff --git a/_posts/2009-01-10-stashing-your-changes.textile b/_posts/2009-01-10-stashing-your-changes.textile new file mode 100644 index 0000000..7c826da --- /dev/null +++ b/_posts/2009-01-10-stashing-your-changes.textile @@ -0,0 +1,37 @@ +--- +layout: post +title: Verstaue deine Änderungen +category: beginner +--- + +Änderungen verstauen (Stashing) ist eine großartige Möglichkeit eine Pause bei der Arbeit einzulegen und später zu ihr zurück zu kommen. Du arbeitest beispielsweise an dieser großartigen neuen Funktion, aber jemand hat gerade einen üblen Fehler gefunden, den du beheben mußt. Füge deine Änderungen zum Index hinzu: + +@git add .@ + +Oder du fügst einzelne Dateien deiner Wahl zum Index hinzu. Verstaue deine Änderungen mit: + +@git stash@ + +Und boom! Du bist zurück in deinem ursprünglichen Arbeitszustand. Der Fehler ist behoben? Hol deine Arbeit zurück mit: + +@git stash apply@ + +Du kannst sogar verschiedene Ebenen von Lagern mit Änderungen (Stashes) anlegen, gehe also sicher, dass du + +@git stash list@ + +ausführst, um alle aktuellen Lager (Stashes) anzuzeigen. Solltest du ein Lager tiefer im Stapel anwenden wollen, ist das auch einfach. Das zweite Lager wendest du folgendermaßen an: + +git stash apply stash@{1} + +Du kannst einfach auch das oberste Lager vom Stapel holen, indem du ("Danke jamesgolick!":http://jamesgolick.com/): + +@git stash pop@ + +benutzt. Ein Hinweis zu diesem Befehl, er löscht dieses Lager, wohingegen apply dies nicht macht. Lager (Stashes) können manuell gelöscht werden: + +@git stash drop @ + +Alle Lagerspeicher werden gelöscht mit: + +@git stash clear@ diff --git a/_posts/2009-01-11-reverting-files.textile b/_posts/2009-01-11-reverting-files.textile new file mode 100644 index 0000000..852b182 --- /dev/null +++ b/_posts/2009-01-11-reverting-files.textile @@ -0,0 +1,25 @@ +--- +layout: post +title: Revert Dateien +category: beginner +published: true +translated: true +--- + +Dieses Thema ist eine konstante Quelle der Verwirrung für viele Git Anwender, weil es hierfür mehrere Möglichkeiten gibt. Wir gehen über einige der notwendigen Kommandos, um deine Arbeit rückgängig zu machen. + +Du möchtest auf eine Datei in ihrem ursprünglichen Zustand reverten: + +@git checkout @ + +Ein Problem könnte es damit geben, dass eine Datei und ein Branch gleich benannt sind. Da das Checkout-Kommando für das Reverting auf Dateien und das Auschecken von Branches verwendet wird, mußt du folgende Syntax verwenden (Danke "Norbauer":http://norbauer.com/notebooks/code/notes/git-revert-reset-a-single-file). + +@git checkout -- @ + +Möchtest du alle Änderungen, an denen du gearbeitet hast, wegwerfen, gibt es hierfür zwei Möglichkeiten. + +@git checkout -f@ or @git reset --HARD@ + +Sobald diese Kommandos ausgeführt werden, wirst du die gesamte Arbeit verlieren, die du nicht committed hast. Stelle also sicher, dass du die Kommandos mit Vorsicht verwendest. + +Beachte auch, dass "'git revert' nicht äquivalent mit 'svn revert'!":http://bryan-murdock.blogspot.com/2007/07/git-revert-is-not-equivalent-to-svn.html ist. @git-revert@ wird für das Umdrehen (reverse) von Commits verwendet. Ein zukünftiger Tip wird das Thema abdecken. diff --git a/_posts/2009-01-12-fixing-broken-commit-messages.textile b/_posts/2009-01-12-fixing-broken-commit-messages.textile new file mode 100644 index 0000000..fac8d87 --- /dev/null +++ b/_posts/2009-01-12-fixing-broken-commit-messages.textile @@ -0,0 +1,45 @@ +--- +layout: post +title: Misslungene Committ-Nachrichten korrigieren +category: advanced +published: true +translated: true +--- + +Du hast soeben diese großartige Feature, den Test, die Fehlerbehebung committed, aber etwas ist einfach nicht korrekt. Entweder ist eine Information nicht ausgefüllt, die Commit-Nachricht ist falsch oder etwas anderes lief einfach total schief. Wir betrachten nun, was du tun kannst, um die betroffenen Daten nachträglich zu korrigieren. + +Der vorangegangene Commit kann sehr einfach korrigiert werden. Verwende einfach + +@git commit --amend@ + +Das wird dir den Commit-Patch im $EDITOR öffnen, um damit zu arbeiten. Bearbeite einfach die Nachricht in der obersten Zeile der Datei, speichere sie ab, beende den Editor und schon bist du fertig. + +Laß uns annehmen, du hast ein paar Commits zu korrigieren, oder der kaputte Commit liegt ein paar Commits zurück. Der Ablauf hierfür ist etwas komplexer, aber es ist nicht so schlimm. (Danke an "Evan Phoenix":http://blog.fallingsnow.net/.) + +Hier ist das Szenario: Die letzten 3 Commits haben den falschen Benutzername und die falsche E-Mailadresse, oder vielleicht auch die falsche Commit-Nachricht. Zunächst erstellen wir für die Commits die entsprechenden Patch-Dateien: + +@git format-patch HEAD^^^@ + +Es werden Dateien in der Form 0001-commit-message erzeugt, die die Commit-Diffs und Metadaten enthalten. Ein Hinweis zu den drei Caret Symbolen: Füge einfach eins pro Commit hinzu, die du zurück gehen möchtest, und sei konsistent! *Update:* Auf die letzten Commits kannst du auch mit der Syntax HEAD~n verweisen, in diesem Beispiel würden wir HEAD~3 verwenden. Fahre fort und bearbeite diese Dateien, so dass sie die passenden Informationen erhalten. Sobald du fertig bist, setzt du dein Repository um ein paar Commits zurück: + +@git reset --hard HEAD^^^@ + +Jetzt kann jeder Commit angewendet werden und die Informationen werden behoben. Stelle die richtige Reihenfolge sicher! (gewöhnlich in aufsteigender Reihenfolge) + +
+git am < 0001...
+git am < 0002...
+git am < 0003...
+
+ +Wenn du jetzt @git log@ überprüfst, solltest du die richtigen Informationen sehen. Ist etwas schief gegangen, holt dich ein + +@git reset --hard origin/master@ + +zurück zu deinen ursprünglichen Änderungen. Sobald deine Informationen korrigiert sind, wirst du das Hochladen (Push) zum Repository erzwingen müssen: + +@git push -f@ + +Wenn du @-f@ nicht hinzufügst, wird sich Git beschweren. *WARNUNG!* Bitte beachte, dass die Änderung von Commit-Nachrichten das Repository von anderen Entwicklern verhunzen könnte und sollte deshalb mit Vorsicht benutzt werden. Andere Entwickler könnten dich dafür hassen. Sollte es weit genug zurück liegen, ist es wahrscheinlich eine schlechte Idee, die "Historie neu zu schreiben.":http://www.youtube.com/watch?v=BytKSy8M4bk + +Solltest du unerwartete oder unentdeckte Konsequenzen kennen, lass sie uns bitte in den Kommentaren wissen. Ein weiterer zukünftiger Tipp wird sich mit dem Korrigieren von tatsächlich übergebenen Dateien befassen und sicherstellen, dass alle Repositories aktuell sind. diff --git a/_posts/2009-01-13-visualizing-your-repo.textile b/_posts/2009-01-13-visualizing-your-repo.textile new file mode 100644 index 0000000..2e2a16a --- /dev/null +++ b/_posts/2009-01-13-visualizing-your-repo.textile @@ -0,0 +1,36 @@ +--- +layout: post +title: Das Repository visualisieren +category: intermediate +published: true +--- + +Du möchtest dein Repository in einer brandneuen Art sehen. Du hast die Nase voll von der Kommandozeile und möchtest ein paar Diagramme sehen. Pixel! Schaltflächen! Graphiken! Dialogboxen! Ok, wir haben verstanden. + +Die erste Option besteht darin, das Repository im Browser anzusehen. Diese Funktionalität ist mit den meisten Git-Installationen packetiert: + +@git instaweb@ + +Das startet einen Server, gewöhnlich "lighttpd":http://lighttpd.net, um eine einfache Webdarstellung deines Repositories anzubieten. Du kannst durch Commits und Trees blättern, sowie Dateien anzeigen, alles was du hast. + +p=. !/images/instaweb.png! + +Das ist wirklich nützlich, wenn du in die Historie eintauchen möchtest, aber die Kommandos dafür noch nicht kennst. (Und es ist auch viel einfacher). Wenn du lighttpd nicht installiert hast und dich nicht damit plagen möchtest, + +@git instaweb --httpd webrick@ + +zwingt WEBrick die Seite zu bedienen, dass so gut funktioniert, als wenn Ruby auf deinem System installiert ist. Es funktioniert auch mit Apache, schaue einfach in der "instaweb Man Page":http://www.kernel.org/pub/software/scm/git/docs/git-instaweb.html nach den unterstützten Servern und anderen Perlen. + +Webseiten sind großartig und alles, aber was wenn du deine Commits in einer eher ... graphischen Art sehen möchtest? Schaue nicht weiter als gitk oder gitx. Diese Programme geben dir eine dynamischere Ansicht auf dein Repository und erlauben dir Entwicklungszweige und Merges zu sehen: + +p=. !/images/gitk.png! + +Benutze gitk aus deiner Git-Installation indem du @gitk@ ausführst oder "lade dir gitx für OSX":http://gitx.frim.nl/ herunter. Wenn die Windows-Anwender etwas kennen, lassen sie bitte einen Kommentar da. + +Es gibt genügend graphische Darstellungen für git auf "GitHub":http://github.com für jedes Projekt. Sei es die Darstellung der Auswirkungen eines Einzelnen auf das Projekt, Zeiten, in denen am Projekt gearbeitet wurde oder viel mehr. Spiele einfach mit den verschiedenen Darstellungen herum und finde heraus, was sie dir anbieten können. + +p=. !/images/impact.png! + +p=. !/images/punchcard.png! + +Es gibt auch eine Reihe guter Darstellungen im "GitWiki":http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#head-60c66fc11f2aaab74873cbb3c434f2075abd5d87. Falls du andere Möglichkeiten kennst, dein Repository graphisch darzustellen, teile es uns in einem Kommentar mit. Ich werde den Beitrag aktualisieren, sobald mehr Informationen dazu verfügbar sind. diff --git a/_posts/2009-01-14-interactive-adding.textile b/_posts/2009-01-14-interactive-adding.textile new file mode 100644 index 0000000..d07fb26 --- /dev/null +++ b/_posts/2009-01-14-interactive-adding.textile @@ -0,0 +1,58 @@ +--- +layout: post +title: Interaktives Hinzufügen +category: intermediate +published: true +translated: true +--- + +Manchmal ist das einfache Hinzufügen mit @git add .@ oder @git commit -am@ nicht genug. Du möchtest deine Änderungen vielleicht in verschiedene kleine Commits aufteilen, oder du bist einfach noch nicht bereit alles hinzuzufügen. Und wer möchte schon einzelne Dateien auf einmal hinzufügen? Das ist langweilig. Öffne den interaktiven Modus mit: + +@git add -i@ + +und wir gehen durch ein Beispiel. Ich habe ein paar Änderungen zur Readme im "gitready":http://github.com/qrush/gitready Projekt zusammen mit ein paar anderen Dateien vorgenommen. Das o.g. Kommando bringt uns folgende Ausgabe, der Status des Index: + +
+         staged     unstaged path
+1:    unchanged        +3/-1 README.md
+2:    unchanged        +1/-1 _layouts/default.html
+
+*** Commands ***
+1: status   2: update  3: revert  4: add untracked
+5: patch    6: diff    7: quit    8: help
+What now> 
+
+ +Wie du sehen kannst, stehen uns eine Reihe von Befehlen zur Verfügung. Das @status@ Kommando zeigt uns diese Ausgabe erneut. +3/-1 sind Nummern von Zeilen, die hinzugefügt/entfernt worden sind, die gewöhnliche Plus- und Minussymbole, die du beim Ziehen (pull) siehst. + +Wir fügen die Änderungen an der Readme hinzu. Das @update@ Kommando erlaubt uns diesen Schritt. Danach sehen wir folgende Ausgabe: + +
+           staged   unstaged path
+* 1:    unchanged      +3/-1 README.md
+  2:    unchanged      +1/-1 _layouts/default.html
+Update>>
+
+ +Sobald wir Update 1 auswählen, wird uns mitgeteilt, dass die Datei für den Commit bereitgestellt ist. Wenn wir in den Status schauen, sehen wir, dass unsere Readme korrekt bereitgestellt ist. + +
+          staged  unstaged  path
+1:        +3/-1    nothing  README.md
+2:    unchanged      +1/-1  _layouts/default.html
+
+ +Sobald du fertig bist, kannst du mit dem @quit@ Kommando abschließen und deine Arbeit wird committed. Solltest du dem interaktiven Modus nicht trauen, zeigt dir @git status@, dass nur die Readme für den Commit bereitgestellt wurde: + +
+# On branch master
+# Changes to be committed:
+#
+# modified:   README.md
+#
+# Changed but not updated:
+#
+# modified:   _layouts/default.html
+
+ +Es gibt noch eine Reihe von hilfreichen Kommandos zum interaktiven Hinzufügen. Das ist erst der Anfang. Schau dir das @help@ Kommando an, der Rest ist dir überlassen. Für weiteren verfügbaren Kommandos im interaktiven Modus, gibt es bald weitere Tips. diff --git a/_posts/2009-01-15-piecemeal-staging.textile b/_posts/2009-01-15-piecemeal-staging.textile new file mode 100644 index 0000000..5688e6b --- /dev/null +++ b/_posts/2009-01-15-piecemeal-staging.textile @@ -0,0 +1,89 @@ +--- +layout: post +title: Schrittweise Commits an den Index +category: advanced +published: true +translated: true +--- + +Das ist eine Fortschreibung des gestrigen Artikels über das "interactive Hinzufügen":http://de.gitready.com/intermediate/2009/01/14/interactive-adding.html. Die Leser baten um einen Artikel zum mächtigen @git add -p@ Kommando, eine Abkürzung zum Patch-Modus beim interaktiven Hinzufügen. Dieses Kommando ist in der Lage, Änderungen in Dateien in kleinere Brocken (hunks) aufzuteilen, so dass du *exakt* das committen kannst, was du möchtest, und nicht nur die gesamte Datei. + +Das Verhalten ist sehr hilfreich. Es erlaubt jeden "Brocken" (hunk) in einer Datei zu versionieren. Die Codezeile bricht vielleicht den Build auf den Maschinen anderer oder auf dem Build-Server, aber nicht bei dir. Du verstehst, was ich meine. + +Gehen wir durch ein Beispiel und nehmen wieder Änderungen an der README Datei vor. @git diff@ zeigt uns folgende vorgenommenen Änderungen an: + +
+diff --git a/README.md b/README.md
+index 2556dae..45d8b6e 100644
+--- a/README.md
++++ b/README.md
+@@ -1,6 +1,14 @@
+> There is only one way...
+> ~ Henry Van Dyke
+   
++# Project information
++
++Blah blah blah...
++
+# Want to contribute?
+
+If you have ideas about... 
++
++# About
++
++This blog is just awesome.
+
+ +Es wurden Änderungen an verschiedenen Stellen in der Datei vorgenommen. Ich möchte jedoch nur die untere Hälfte übergeben. Außerdem, wer braucht schon wirklich Dokumentation? Gib folgendes ein: + +@git add -p@ + +Und du wirst mit einer Eingabeaufforderung begrüßt, ähnlich wie sie @git add -i@ anbietet, aber sie hat ziemlich viele Optionen: + +
+Stage this hunk [y/n/a/d/s/e/?]? ?
+y - stage this hunk
+n - do not stage this hunk
+[... removed a few ...]
+s - split the current hunk into smaller hunks
+e - manually edit the current hunk
+? - print help
+
+ +Die meisten Optionen sind selbsterklärend, aber wir gehen einfach über die wirklich coolen Optionen. Wir fokusieren uns auf die @s@ Option, die die Datei in kleinere Code-Brocken (hunks) aufteilen wird, einen oberen "Project Information" Block und einen unteren "About" Block. Sobald alles aufgeteilt ist, wird es dich nur zu den Änderungen zu diesem Brocken befragen: + +
+Split into 2 hunks.
+@@ -1,6 +1,10 @@
+> There is only one way...
+> ~ Henry Van Dyke
+
++# Project information
++
++Blah blah blah...
++
+# Want to contribute?
+
+If you have ideas about...
+Stage this hunk [y/n/a/d/j/J/e/?]? n
+
+ +Hier ignorieren wir den Brocken mit @n@ und gehen weiter zum nächsten Brocken und fügen ihn mit @y@ hinzu: + +
+@@ -4,3 +8,7 @@
+# Want to contribute?
+
+If you have ideas about...
++
++# About
++
++This blog is just awesome.
+Stage this hunk [y/n/a/d/K/e/?]? y
+
+ +@git status@ zeigt uns die zu committenden Änderungen und die Änderungen, die für eine Datei auf die staging area kommen. Komisch, aber es macht Sinn: Wir haben die Hälfte der Änderungen auf die staging area gehoben und die andere Hälfte wurde noch nicht zum Index hinzugefügt. + +Es gibt auch die @e@ Option, die das manuelle An- und Abschalten der Brocken in deinem Lieblingseditor erlaubt. Die Option beinhaltet Instruktionen, spiele also damit ein wenig herum, sobald du die Gelegenheit dazu hast (Das ist kein Wortspiel). + +Solltest du weitere Geschichten haben, wie dir @git add -p@ geholfen hat (oder falls ein Feature fehlt), teile es uns in einem Kommentar mit! diff --git a/_posts/2009-01-16-cleaning-up-untracked-files.textile b/_posts/2009-01-16-cleaning-up-untracked-files.textile new file mode 100644 index 0000000..ec432e0 --- /dev/null +++ b/_posts/2009-01-16-cleaning-up-untracked-files.textile @@ -0,0 +1,42 @@ +--- +layout: post +title: Untracked Dateien aufräumen +category: beginner +published: true +--- + +Unser erster eingereichter Tip kommt von "Dav Glass":http://blog.davglass.com/. Er führt näher aus, wie das Repository schön sauber gehalten werden kann. Hast du einen Tip, den du teilen möchtest? "Reiche einen Tip ein!":http://de.gitready.com/submit.html + +Dateien und Verzeichnisse können sich in deinem Arbeitsverzeichnis anhäufen, die von Merges übrig blieben, erstellt oder fälschlicherweise dort abgelegt wurden. Was auch immer der Fall ist, du musst sie nicht in deine @.gitignore@-Datei eintragen. Du kannst sie einfach entfernen. + +@git clean -n -d @ + +macht einen 'Trockenlauf' des Befehls und zeigt dir, welche Dateien und Verzeichnisse entfernt werden. Auf "gitready":http://github.com/qrush/gitready ausgeführt, kommt folgende Ausgabe: + +
+Would remove _posts/2009-01-16-cleaning-up-untracked-files.textile
+
+ +Es wäre definitiv schlecht, wenn die Datei entfernt werden würde. Ich habe den Beitrag noch nicht zur staging Area hinzugefügt, so dass sie als "untracked" gilt. Wenn du nur Dateien und keine leeren Verzeichnisse aufräumen möchtest, lasse die @-d@ Option weg. Sobald du sicher bist, dass du all diese Dateien entfernen möchtest, so entfernt ein + +@git clean -d @ + +die Dateien. Wenn du @@ wegläßt, wird Git den Befehl im aktuellen Verzeichnis ausführen. Vielleicht musst du noch die @-f@ Option einfügen, abhängig von Rechten und anderen Situationen, die aufkommen können. + +Aufräumen hat noch ein paar andere nützliche Optionen: Wenn du normal aufräumen möchtest und alle Dateien löschen willst, die Git gewöhnlich ignoriert, so wird dir die @-x@ Option dabei behilflich sein. Wenn du die ignorierten Dateien einfach wegwerfen möchtest, so reicht die @-X@ Option. + +Für einen Großputz hilft: + +
+$ git clean -n -d -x
+Would remove .DS_Store
+Would remove _posts/.2009-01-16-cleaning-up-untracked-files.textile.swp
+Would remove _posts/2009-01-16-cleaning-up-untracked-files.textile
+Would remove _site/
+Would remove images/.DS_Store
+Would remove images/_site/
+
+ +Der Befehl räumt Dateien und Verzeichnisse auf, die nicht mehr nötig sind und Dateien, die in der ".gitignore":http://github.com/qrush/gitready/blob/7f51407b796c10beb11fe9e67c0f563d41a92fd8/.gitignore Datei des Projekts genannt sind. Wie immer, sei vorsichtig bei der Verwendung von @git clean@ und prüfe, was du wirklich löschst. + +Wie immer, wenn du andere ähnliche Tricks mit @git clean@ kennst, teile sie uns in den Kommentaren mit!. diff --git a/_posts/2009-01-17-restoring-lost-commits.textile b/_posts/2009-01-17-restoring-lost-commits.textile new file mode 100644 index 0000000..8607b06 --- /dev/null +++ b/_posts/2009-01-17-restoring-lost-commits.textile @@ -0,0 +1,54 @@ +--- +layout: post +title: Verlorene Commits wieder herstellen +category: advanced +published: true +--- + +Du hast ein @git reset --hard HEAD^@ durchgeführt und soeben deinen letzten Commit weg geworfen. Es stellt sich jedoch heraus, dass du diese Änderungen wirklich brauchst. Du wirst niemals in der Lage sein, den Algorithmus ein zweites Mal so perfekt zu implementieren, also willst du ihn zurück haben. Keine Panik! Git sollte den Commit noch haben. Wenn du einen Reset durchführst, geht der weggeworfene Commit in einen "baumelnden" Status über. Er befindet sich weiterhin in Gits Datenspeicher und wartet auf die nächste Müllsammlung (garbage collection), um aufgeräumt zu werden. Sofern du seit dem Wegwurf kein @git gc@ ausgeführt hast, solltest du den Commit wieder herstellen können. + +Für die Beispiele arbeite ich mit dem "Code für dieses Blog":http://github.com/gitready/gitready: + +
+$ git show-ref -h HEAD
+  7c61179cbe51c050c5520b4399f7b14eec943754 HEAD
+
+$ git reset --hard HEAD^
+  HEAD is now at 39ba87b Fixing about and submit pages so they don't look stupid
+
+$ git show-ref -h HEAD
+  39ba87bf28b5bb223feffafb59638f6f46908cac HEAD
+
+ +Unser @HEAD@ ist um einen Commit zurück gesetzt worden. Mit @git pull@ können wir einfach an diesen Punkt zurück kehren. Aber wir nehmen an, dass nur unser lokales Repository von dem Commit weiß. Wir benötigen den SHA1-Hash des Commits, um sie zurück zu holen. Mit dem @fsck@ Befehl können wir zeigen, dass Git den Commit noch kennt: + +
+$ git fsck --lost-found
+  [... some blobs omitted ...]
+  dangling commit 7c61179cbe51c050c5520b4399f7b14eec943754
+
+ +Mit dem @reflog@ Befehl kannst du ebenfalls sehen, dass Git den Commit noch kennt: + +
+$ git reflog
+  39ba87b... HEAD@{0}: HEAD~1: updating HEAD
+  7c61179... HEAD@{1}: pull origin master: Fast forward
+  [... lots of other refs ...]
+
+ +Jetzt haben wir unseren SHA1-Hash: @7c61179@. Wenn wir den Commit sofort in unseren aktuellen Branch zurück haben möchten, erledigt das @git merge@ für uns: + +
+$ git merge 7c61179
+  Updating 39ba87b..7c61179
+  Fast forward
+    css/screen.css |    4 ++++
+    submit.html    |    4 ++--
+    2 files changed, 6 insertions(+), 2 deletions(-)
+
+ +Dieser Befehlt holt unsere verlorenen Änderungen zurück und stellt sicher, das @HEAD@ auf den Commit zeigt. Von hier aus kannst du mit der Arbeit normal fortfahren! Du kannst mit dem SHA1-Hash in einen neuen Branch beginnen, aber ein Merge ist die schnellste und einfachste Art, einen verlorenen Commit wieder herzustellen, sobald du den Hash hast. Wenn du andere Alternativen kennst, teile sie uns in den Kommentaren mit! + +Wenn du dir weitere Optionen für diese Situation ansehen möchtest, so verfügt "Mathieu Martin's":http://programblings.com/ " +illustrated guide to recovering lost commits with Git":http://programblings.com/2008/06/07/the-illustrated-guide-to-recovering-lost-commits-with-git über genügend Material. diff --git a/_posts/2009-01-18-the-staging-area.textile b/_posts/2009-01-18-the-staging-area.textile new file mode 100644 index 0000000..64aaa40 --- /dev/null +++ b/_posts/2009-01-18-the-staging-area.textile @@ -0,0 +1,69 @@ +--- +layout: post +title: Der Staging Bereich +category: beginner +published: true +translated: true +--- + +Eines der essentiellsten Konzepte von Git ist jenes der staging area. Seine Verwendung kann deine Arbeitsweise fundamental zum Besseren ändern! Lass uns darüber schauen, wie er tatsächlich funktioniert und was du für die Verwendung brauchst. + +Bei den meisten anderen Versionskontrollsystemen gibt es zwei Orte für das Speichern der Daten: Deine Arbeitskopie (die Verzeichnisse/Dateien, die du gegenwärtige benutzt) und der Datenspeicher (wo die Versionskontrolle entscheidet wie deine Änderung verpackt und gespeichert werden). In Git gibt es eine dritte Option: Die staging area oder Index. Es ist quasi ein Ladedock, wo du entscheidest welche Änderungen verschifft werden. + +p=. "!http://farm4.static.flickr.com/3259/2441544705_4c6f7e9b78.jpg!":http://flickr.com/photos/mundane_joy/2441544705/ + +Die essentielle Entkopplung von Arbeitsverzeichnis und was Git speichert, erlaubt den Entwicklern ihre Commits so zusammenzubauen, wie sie es wünschen und nicht auf eine Art und Weise, wie es das VCS von ihnen erwartet. Du erlangst viel mehr Flexibilität und Kontrolle dadurch, dass Git eine Ebene zwischen den tatsächlich gespeicherten Daten verwendet. + +Die Verwendung des Index geht recht einfach mit den Kommandos @git add@ und @git commit@ vonstatten. Du fügst Dateien zum Index hinzu (@add@) und sobald du zufrieden mit deinen Änderungen bist, stellst du sie bereit (@commit@): + +p=. "!http://whygitisbetterthanx.com/images/index1.png!":http://whygitisbetterthanx.com/#the-staging-area + +Sobald sie im Repository sind, kannst du sie an einen entfernten Ort pushen (@push@), mit anderen Branches zusammenfügen (@merge@) und vieles mehr. Es gibt auch Aktionen, die auf der staging area selbst ausgeführt werden können, zum Beispiel "Änderungen temporär lagern":http://de.gitready.com/beginner/2009/01/10/stashing-your-changes.html. + +Lass uns durch ein einfaches Beispiel für die Verwendung der staging area gehen. Ich habe gerade ein paar Änderungen vorgenommen: + +
+$ git status
+  On branch master
+  Changed but not updated:
+    (use "git add ..." to update what will be committed)
+
+      modified:   README.md
+      modified:   about.html
+
+  Untracked files:
+    (use "git add ..." to include in what will be committed)
+
+      help.txt
+  no changes added to commit (use "git add" and/or "git commit -a")
+
+ +In dem Beispiel haben wir 2 Dateien, über die Git Bescheid weiß, und eine Datei, die es nicht kennt: help.txt. Wenn wir ein @git add .@ ausführen, werden alle Änderungen oder jede neue Datei, die nicht getracked wird, hinzugefügt. Das @add@ Kommando speichert die Daten noch nicht, es platziert sie lediglich auf das Ladedock, bereit für den nächsten @git commit@ Laster, der sie mitnimmt. + +
+$ git add .
+$ git status
+  On branch master
+  Changes to be committed:
+    (use "git reset HEAD ..." to unstage)
+
+      modified:   README.md
+      modified:   about.html
+      new file:   help.txt
+
+ +Wie der Prompt sagt, kannst du @git reset HEAD @ benutzen, um Dateien zurück in ihren modifizierten Zustand zu versetzen. Auf diese Weise kannst du genau das bereitstellen, was du möchtest. "Du kannst sogar spezifische Zeilen in Dateien committen, wenn du wirklich willst":http://de.gitready.com/advanced/2009/01/15/piecemeal-staging.html. Solltest du dich darüber wundern, wie Daten zurück gesetzt werden können, "dazu gibt es auch einen eigenen Tip":http://de.gitready.com/beginner/2009/01/11/reverting-files.html. Von hier aus befördert ein @git commit@ alle Dateien in Gits Datenspeicher und du bist fertig. + +
+$ git commit -m "Adding stuff"
+  Created commit e793200: Adding stuff
+   2 files changed, 3 insertions(+), 0 deletions(-)
+   create mode 100644 help.txt
+
+ +Solltest du nach mehr Informationen zum Index suchen, schaue dir diese fantastischen Beiträge an: + +# "The Thing About Git":http://tomayko.com/writings/the-thing-about-git +# "Git Book - The Git Index":http://book.git-scm.com/1_the_git_index.html + +Solltest du weitere Quellen kennen, die den Index erklären, lass sie uns in den Kommentaren wissen. diff --git a/_posts/2009-01-19-ignoring-files.textile b/_posts/2009-01-19-ignoring-files.textile new file mode 100644 index 0000000..5adb7e1 --- /dev/null +++ b/_posts/2009-01-19-ignoring-files.textile @@ -0,0 +1,40 @@ +--- +layout: post +title: Dateien ignorieren +category: beginner +published: true +--- + +Git muss nicht alles in unserem Projekt versionieren. Seien es kompilierte Quellen, Dateien mit Passwörter oder temporäre Dateien, die gerne erstellt werden. Zeugs aus der Verwaltung des VCS herauszuhalten, ist gewöhnlich eine schwer zu verwaltende und ärgerliche Aufgabe. Nicht mit Git! Mit der @.gitignore@ Datei und ein paar anderen Optionen lernen wir, wie Ignore-Regeln pro Projekt und pro Benutzer aufgesetzt werden können. + +p=. "!http://farm1.static.flickr.com/4/7240060_1332e880ff.jpg!":http://flickr.com/photos/miskan/7240060/ + +Am einfachsten ist das Erstellen der @.gitignore@ Datei im Hauptverzeichnis deines Projekts. Die zum Ignorieren ausgewählten Dateien werden alle Verzeichnisse in deinem Projekt betreffen. Es sei denn einzelne Verzeichnisse haben ihre eigene @.gitignore@ Datei. Das ist besonders schön, weil es einen Ort für diese Konfiguration gibt, nicht wie SVNs svn:ignore, dass für jedes Verzeichnis gesetzt werden musste. Darüber hinaus werden die Ignore-Dateien selbst versioniert. + +Hier ist eine einfache @.gitignore@ Datei: + +
+$ cat .gitignore
+
+# Can ignore specific files
+.DS_Store
+
+# Use wildcards as well
+*~
+*.swp
+
+# Can also ignore all directories and files in a directory.
+tmp/**/* 
+
+ +Natürlich kann die Datei beliebig komplex werden. Du kannst auch Ausnahmen zu den Ignore-Regeln festlegen, indem die Zeile mit @!@ beginnt. Im "GitHub guide on ignores":http://github.com/guides/ignore-for-git gibt es dazu ein Beispiel. + +Zwei Dinge solltest du beim Umgang mit Ignore-Dateien im Hinterkopf behalten: Erstens, wenn die Datei schon von Git verwaltet wird, wird sie trotz Hinzufügen in @.gitignore@ weiterhin getracked. Du musst @git rm --cached @ ausführen, um die Datei im Verzeichnisbaum zu behalten und sie dann ignorieren. Zweitens, leere Verzeichnisse werden nicht von Git verwaltet. Wenn leere Verzeichnisse von Git verwaltet werden sollen, müssen sie eine Datei beinhalten. Gewöhnlich reicht ein @touch .gitignore@ aus. + +Du kannst auch @$GIT_DIR/info/exclude@ öffnen (@$GIT_DIR@ ist normalerweise dein @.git@ Verzeichnis) und diese Datei für Ignores nur das Projekt betreffend editieren. Das Problem besteht allerdings darin, dass diese Änderungen nicht von Git verwaltet werden. Benutze diese Variante also nur, wenn du ein paar persönliche Dateien hast, die du nicht mit anderen in diesem Projekt teilen möchtest. + +Die abschließende Option zum Ignorieren von Verzeichnissen betrifft die benutzerorientierten Ignore-Regeln, die mit der @core.excludesfiles@ Option in der Konfigurationsdatei aktiviert werden. Du kannst auch eine @.gitignore@ Datei in deinem HOME Verzeichnis anlegen. Sie betrifft alle deine Repositories, nachdem du folgenden Befehl ausgeführt hast: + +@git config --global core.excludesfile ~/.gitignore@ + +Lies die "Manpage":http://www.kernel.org/pub/software/scm/git/docs/gitignore.html, wenn du mehr darüber lernen möchtest, wie Ignores arbeiten. Wenn du einen Tipp zum Thema Ignorieren von Dateien hast, teile ihn uns in den Kommentaren mit. diff --git a/_posts/2009-01-20-bend-logs-to-your-will.textile b/_posts/2009-01-20-bend-logs-to-your-will.textile new file mode 100644 index 0000000..da2de11 --- /dev/null +++ b/_posts/2009-01-20-bend-logs-to-your-will.textile @@ -0,0 +1,50 @@ +--- +layout: post +title: Logs nach eigenem Willen verbiegen +category: advanced +published: true +--- + +@git log@ ist ein extrem mächtiger Befehl mit einer Reihe von Optionen. Er ist äußerst nützlich, um herauszufinden, welche Arbeit im Repository durch wen gemacht wurde. Dieser Beitrag listet ein paar mehr Optionen auf. Die meisten Tipps wurden aus Scott Chacons "gitcast on git log":http://gitcasts.com/posts/git-log und R. Tyler Ballances "git protip series":http://unethicalblogger.com/posts/2008/12/git_protip_learning_your_history_git_log entnommen. + +@git log -@ + +Zeigt das Log für @n@ Commits. @git log -2@ zum Beispiel zeigt die letzten zwei Commits. + +@git log --stat@ + +Zeigt das Log mit einer Darstellung für geänderte Dateien und deren Inserts/Deletions. Im Grunde genommen handelt es sich um die normale Ausgabe von @git commit@, die an jeden Logeintrag angehängt wird. + +@git log --name-status@ + +Hängt SVN-ähnliche add/modified/deleted Informationen für jeden Commit an. Das ist recht einfach, liefert aber eine anständige Idee davon, was sich geändert hat. + +@git log --pretty=oneline@ + +Reduziert jeden Commit auf seinen SHA und seine Nachricht auf eine Zeile. Über eine Pipe an @wc -l@ übergeben, wird die Anzahl der Übergaben gezählt! + +@git log origin..HEAD@ + +Zeigt Commits, die noch nicht an deinen @origin@ Remote hochgeladen wurden. (Danke für den Tip, Ryan Bates!) + +@git log @ + +Zeigt alle Commits, die nur eine Datei betreffen. + +@git log --no-merges --author=dave@ + +Zeigt alle Commits, an denen dave gearbeitet hat und ignoriert alle Merges, um das "Rauschen" zu unterdrücken. + +@git log --since="1 week ago"@ + +Gibt alle Commits aus, die in der vergangenen Woche hinzugefügt wurden. Die Option kann einfach mit @yesterday@ (gestern), @1 year ago@ (vor einem Jahr), @3 months ago@ (vor drei Monaten), @1/20/09@ und so weiter ersetzt werden. Es gibt auch anderen zeitbasierte Optionen: @--after@, @--until@ und @--before@, falls du kreativ werden möchtest. + +@git log --grep='^Bump'@ + +Durchsucht die Commit-Nachricht nach jenen Commits, die mit der Zeichenkette "Bump" beginnen. Der Befehl nimmt jegliche regulären Ausdrücke entgegen. Du suchst nach einem Commit und du kannst dich nur an einen Teil der Commit-Nachricht erinnern? @--grep@ wird sie finden. + +@git --no-pager log@ + +Du möchtest kein @less@ für die Ausgabe des Commit benutzen? Diese Option liefert dir die direkte Ausgabe, falls du sie brauchst. + +Natürlich kannst du die "Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-log.html für alle verfügbaren Optionen konsultieren. Wenn du einen nützlichen Tip hast, den wir vergessen haben und du ihn gerne mitteilen möchtest, hinterlasse uns einen Kommentar und wir aktualisieren den Beitrag. diff --git a/_posts/2009-01-21-pushing-and-pulling.textile b/_posts/2009-01-21-pushing-and-pulling.textile new file mode 100644 index 0000000..24eee0f --- /dev/null +++ b/_posts/2009-01-21-pushing-and-pulling.textile @@ -0,0 +1,52 @@ +--- +layout: post +title: Push und Pull +category: beginner +published: true +translated: true +--- + +Heute schauen wir ein weiteres mächtiges Grundkonzept an, das Git gegenüber anderen Versionskontrollsystemen besitzt: Verteilung! Wie du vielleicht weißt, sind deine Commits alle lokal und Repositories sind einfach nur Klone voneinandern. Die wirkliche Arbeit im Verteilen deines Projekts fällt beim Synchronisieren deiner Änderungen mit @git push@ und @git pull@ an. + +Das sind viel zu hohe Unkosten die zu einem Zusammenbruch der Kontrolle führen, mag der Gitneuling vielleicht denken. Betrachte es auf diese Weise: Wenn dein Server ausfällt, wirst du meist daran gehindert weiter zu arbeiten und mit anderen zusammen zu arbeiten. Die tatsächliche Arbeit besteht im Erstellen von Revisionen auf deiner eigenen Maschine. Somit kannst du weiter programmieren, ob das Netzwerk nicht verfügbar ist oder sonstige Netzwerkprobleme bestehen. Habe ich schon erwähnt, dass Git bei Routineaufgaben um einiges Schneller ist? Weitere Vor- (und Nachteile) von DCVS gibt es auf "Wikipedia":http://en.wikipedia.org/wiki/Distributed_revision_control#Vs_Centralised. + +"Oliver Steele":http://osteele.com hat ein großartiges Bild zur Arbeitsweise von Push und Pull erstellt. + +p=. !http://osteele.com/images/2008/git-transport.png! + +Der oberste Teil des Schaubilds ist einfach, deine Änderungen werden auf der "staging area":http://de.gitready.com/beginner/2009/01/18/the-staging-area.html bereitgestellt. Sobald das erledigt ist, befindet sich deine Versionskontrolle am richtigen Platz, aber jetzt möchten wir es mit dem entfernten Repository abgleichen. Das kann ein Hoster wie "GitHub":http://github.com sein, dein Git-Arbeitsserver, eine Produktiv-Maschine oder sogar das Repository eines Kollegen. Sobald die Änderungen ausgeliefert sind, können andere diese beziehen (@pull@) und mit ihnen arbeiten. Bei den meisten Aktionen in Git gibt es ein paar Optionen, aber heute bleiben wir bei @pull@. + +Wir gehen durch ein reales Beispiel. Ich habe den "Twitter":http://twitter.com/gitready Link am Fuß dieses Blogs eingefügt. Ich möchte die Änderungen zum "Projekt-Repository auf GitHub":http://github.com/qrush/gitready übertragen (@push@), um den Server zu aktualisieren. Die Syntax für das Kommando lautet @git push @. ist hauptsächlich die Adresse des geklonten Repositorys. Es enthält so ziemlich genau die selben Daten und Historien und wartet darauf aktualisiert zu werden. Die meisten Repositorys arbeiten gewöhnlich mit einer Gegenstelle namens @origin@ und dem Branch @master@. + +
+$ git commit -am "Adding twitter link"
+  Created commit f2cd831: Adding twitter link
+  1 files changed, 1 insertions(+), 0 deletions(-)
+
+$ git push origin master
+  Counting objects: 7, done.
+  Compressing objects: 100% (4/4), done.
+  Writing objects: 100% (4/4), 407 bytes, done.
+  Total 4 (delta 2), reused 0 (delta 0)
+  To git@github.com:qrush/gitready.git
+     361303d..f2cd831  master -> master
+
+ +Jetzt, wo das entfernte Repository, die Gegenstelle, aktualisiert ist und wenn du auf GitHub vorbei schaust, "kannst du die Commits sehen":http://github.com/qrush/gitready/commits/en. Die Kommandoausgabe gibt an, wie Git die geänderten Datenblobs überträgt und läßt uns wissen, dass das Repository aktualisiert ist, indem es den geänderten SHA1-Hash zeigt. + +Aber was ist mit @pull@? Wir können es zum Abgleich der soeben gemachten Commits mit jeglichen Repositories verwenden. Das Projekt-Deployment Script macht genau das: + +
+$ git pull origin master
+  remote: Counting objects: 7, done.
+  remote: Compressing objects: 100% (4/4), done.
+  remote: Total 4 (delta 2), reused 0 (delta 0)
+  Updating 361303d..f2cd831
+  Fast forward
+   _layouts/default.html |    1 +
+    1 files changed, 1 insertions(+), 0 deletions(-)
+
+ +Die Ausgabe zeigt uns, dass das Repository auf dem Server ein paar Änderungen vom entfernten Repository einholen muss und holt diese sogleich ab. Der Prozess wäre exakt derselbe, wenn du Bereitstellungen einer anderen Person in dein Repository einbringen wolltest. Jene, die das "Gitready Repository":http://github.com/qrush/gitready/network/members auf GitHub abgespaltet haben, können nun meine vorgenommenen Änderungen abholen. Zukünftige Tutorien behandeln diesen Prozess in größere Detailtiefe. + +Wenn dir andere Ideen oder Konzepte einfallen, die hier vergessen wurden, lass es uns bitte wissen. diff --git a/_posts/2009-01-22-count-your-commits.textile b/_posts/2009-01-22-count-your-commits.textile new file mode 100644 index 0000000..fa0fd6b --- /dev/null +++ b/_posts/2009-01-22-count-your-commits.textile @@ -0,0 +1,33 @@ +--- +layout: post +title: Commits zählen +category: intermediate +published: true +--- + +Hast du dich jemals gewundert, wie viele Commits du zu einem Projekt beigetragen hast? Oder vielleicht, welcher Mitarbeiter nichts gemacht hat (oder vielleicht hat er große Änderungen in wenigen Commits eingebracht!). Wundere dich nicht länger, @git shortlog@ ist ein schöner Weg, das heraus zu finden. + +Der Befehl wird gegen meinen "Clone von jekyll":http://github.com/qrush/jekyll ausgeführt, der für das Erzeugen dieses Blogs verantwortlich ist: + +
+$ git shortlog -s -n
+  135  Tom Preston-Werner
+  15  Jack Danger Canty
+  10  Chris Van Pelt
+  7  Mark Reid
+  6  remi
+  3  Mikael Lind
+  3  Toby DiPasquale
+  2  Aristotle Pagaltzis
+  2  Basil Shkara
+  2  John Reilly
+  2  PJ Hyett
+  1  Marc Chung
+  1  Nick Gerakines
+  1  Nick Quaranto
+  1  Tom Kirchner
+
+ +Die @-s@ Option führt alle Commit-Nachrichten in die Zahl der Commits zusammen und die @-n@ Option sortiert die Liste nach der Anzahl der Commits. + +Der Befehl kann auch für Changelogs sehr nützlich sein, weil einfach alle Änderungen jeder Person ausgegeben werden können. Es gibt weitere geschickte Optionen: @-e@ fügt E-Mails an und die Spaltenbreite wird mit @-w@ kontrolliert. Schau in der "Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html nach für weitere Informationen. diff --git a/_posts/2009-01-23-bash-git-status.textile b/_posts/2009-01-23-bash-git-status.textile new file mode 100644 index 0000000..da09f6d --- /dev/null +++ b/_posts/2009-01-23-bash-git-status.textile @@ -0,0 +1,28 @@ +--- +layout: post +title: Bash Git Status +category: advanced +published: true +--- + +Wir kennen alle den @git status@ Befehl. Aber das sind einfach zu viele Zeichen, die immer und immer wieder getippt werden müssen. Warum sollte man sich um diese 10 Tastenschläge kümmern, wenn die Shell einfach Gits Arbeitsstatus ausgeben kann? Klingt großartig, richtig? Glücklicherweise haben ein paar Hacker ihre Scripte zusammen geworfen, um genau das in deinem Bash Prompt zu erledigen. Wenn du diese oder ähnliche Scripte in deiner Shell arbeiten läßt, "schicke uns einen Tip dazu!":http://de.gitready.com/submit.html + +p=. !http://farm1.static.flickr.com/72/195355984_7d6153610b.jpg! + +Das wahrscheinlich verbreiteste und bekannteste Script dieser Art "zeigt den aktuellen Branch Namen und ob sich etwas geändert hat.":http://henrik.nyh.se/2008/12/git-dirty-prompt In der @.bashrc@ verankert, erzeugt das Script den folgenden Prompt: + +
+# When clean...
+user@host ~/dir[master]$
+
+# When dirty...
+user@host ~/dir[master*]$
+
+ +So ist es viel einfacher festzustellen, wann ein weiterer Commit nötig ist. Es gibt eine "ganze Reihe von Varianten dieses Scripts auf Gist.":http://gist.github.com/31631 Dieser Hack entwickelte sich daraus, einfach nur "den Branch Namen zu zeigen.":http://www.simplisticcomplexity.com/2008/03/13/show-your-git-branch-name-in-your-prompt/ Benutze die Scripte und bau darauf auf, wie es dir gefällt. + +Oh, du wolltest mehr? Es gibt ein nützliches Projekt namens "git-prompt,":http://github.com/lvv/git-prompt/tree/master dass dir alle möglichen Informationen über das Repository im Bash Prompt gibt. Du kannst heraus finden, ob einzelne Dateien getrackt werden oder sich geändert haben, ob Merge-Konflikte gelöst sind und sogar ob dein @HEAD@ abgelöst ist. "Schau dir die Projektseite an,":http://volnitsky.com/project/git-prompt/ um mehr Informationen zu bekommen, was möglich ist. Hier ist eine kleine Demonstration dazu, was angezeigt werden kann: + +p=. !http://farm4.static.flickr.com/3492/3221797568_41a9803e01_o.png! + +Wenn du andere hilfreiche Prompt-relevante Tips hast, lass sie uns wissen und wir werden sie hinzufügen! diff --git a/_posts/2009-01-24-sharing-your-changes.textile b/_posts/2009-01-24-sharing-your-changes.textile new file mode 100644 index 0000000..18594bf --- /dev/null +++ b/_posts/2009-01-24-sharing-your-changes.textile @@ -0,0 +1,52 @@ +--- +layout: post +title: Änderungen verteilen +category: intermediate +published: true +--- + +Die verteilte Natur von Git ist unabhängig von zentralen Servern zum Hosten und Verteilen des Quellcodes. Es gibt mehrere Optionen, falls aus irgend einem Grund dein Server oder sogar "GitHub ausfällt":http://ozmm.org/posts/when_github_goes_down.html. + +Der wahrscheinlich einfachste Weg deinen Quellcode schnell und einfach zu teilen, ist die Erstellung eines kahlen (bare) Repository-Klons, der nur das Zeug im @.git@-Verzeichnis im Hauptverzeichnis deines Projektordners enthält. Da dieser Ordner die gesamte Projekthistorie beinhaltet, kann alles recht einfach daraus extrahiert werden. Folgende Kommandos sind hierfür auszuführen: + +@git clone --bare ~/Dev/ruby/jekyll jekyll.git@ + +Das Verzeichnis kann auf irgendeinen Server hochgeladen und somit einfach an Andere Entwickler verteilt werden. Das Repository wird wiederhergestellt, indem das Verzeichnis auf deine Maschine kopiert und folgende Kommandos ausgeführt werden: + +
+$ mkdir test
+$ mv jekyll.git test/.git
+$ cd test
+$ git init
+  Reinitialized existing Git repository in /Users/qrush/Dev/test/.git/
+$ git checkout -f
+
+ +Somit haben wir einen neuen Ordner für das Repository erstellt, ändern den Verzeichnisnamen wieder in @.git@, holen Git zurück und stellen alle Änderungen von der neuesten Bereitstellung (Commit) wieder her. + +Du kannst auch @git-daemon@ verwenden, um deine Dateien schnell über das git:// Protokoll bereit zu stellen. Es wird automatisch Projekte in Unterverzeichnissen zur Verfügung stellen. Für mein Ruby-Verzeichnis wird: + +@git daemon --base-path=~/Dev/ruby --export-all@ + +dir erlauben, das jekyll Repository auf eine andere Maschine zu klonen: + +@git clone git:///jekyll@ + +Stelle sicher, dass der Port 4918 in deinem Netzwerk für diese Übertragung geöffnet ist. Wenn nicht, konfiguriere einfach einen anderen Port mit der @--port@ Option. Schau in der "Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-daemon.html nach, falls es für dich noch nicht funktioniert. + +Die Verwendung von TCP ist langweilig! Was ist, wenn du meine Änderungen lieber über HTTP bekommen möchtest? Du hast Glück. Git kann deine Änderungen auch über HTTP zur Verfügung stellen. Die folgenden drei Kommandos erledigen das: + +
+git --bare update-server-info
+mv hooks/post-update.sample hooks/post-update
+chmod a+x hooks/post-update
+
+ +Sie bereiten Git grundsätzlich für den Zugriff über den Webbrowser vor. Es setzt voraus, dass Apache oder dein Lieblingsserver für das Bereitstellen des Verzeichnisses konfiguriert ist. Du solltest damit in der Lage sein, das Repository folgendermaßen zu klonen: + +@git clone http://yoursite.com/yourrepo.git@ + +Es gibt noch eine Reihe weiterer Optionen. Du solltest den Build von "OS X für die Verteilung über das +Web":http://toolmantim.com/articles/sharing_git_repositories_via_os_xs_built_in_web_sharing zusammen mit der bisherigen Technik zum Bereitstellen von deiner Maschine aus benutzen. Du könntest auch noch eine SSH Adresse verwenden, wenn du ein SSH Konto auf dem Server konfiguriert hast, wo du deinen Quellcode verteilen möchtest. + +Solltest du weitere nützliche Ideen zum Teilen deines Repositories haben, hinterlasse uns einen Kommentar! diff --git a/_posts/2009-01-25-branching-and-merging.textile b/_posts/2009-01-25-branching-and-merging.textile new file mode 100644 index 0000000..4f8894c --- /dev/null +++ b/_posts/2009-01-25-branching-and-merging.textile @@ -0,0 +1,101 @@ +--- +layout: post +title: Branchen und Mergen +category: beginner +published: true +--- + +Branchen oder verzweigen ist in Git einfacher, als du denkst. Es ist schnell (40 Zeichen in eine Datei geschrieben), einfach (ein Befehl zum Erzeugen eines Branches) und effizient (es erzeugt keine vollständige Kopie deines aktuellen Arbeitsstatus). Die Branches, die du erzeugst, müssen nicht im Remote Repository existieren, so dass du sie zum Testen neuer Features oder für Bugfixes verwenden kannst, ohne bereits funktionierende Teile zu beschädigen. "Why Git is Better Than X":http://whygitisbetterthanx.com/#cheap-local-branching drückt es wohl am besten aus: + +
+Git will allow you to have multiple local branches that can be entirely independent of each other and the creation, merging and deletion of those lines of development take seconds. [...] Git makes this process incredibly easy and it changes the way most developers work when they learn it. +
+ +Das ist nett, aber du könntest noch Vorbehalte bei der Nutzung von Branches haben, wegen der Assoziationen mit vorangegangenen Versionskontrollsystem und deren Handhabung von Branches. Derartige Sorgen gehören der Vergangenheit an. Wir gehen ein einfaches Beispiel zu Branchen, Mergen und Konfliktlösung durch. + +Ich arbeite wieder mit dem "jekyll":http://github.com/qrush/jekyll Repository. Ich checke einen Branch aus, machen ein paar Änderungen an Dateien und führe sie im Master Branch zusammen. + +
+$ git checkout -b fixes
+  Switched to a new branch "fixes"
+
+$ vim lib/jekyll/core_ext.rb
+
+$ git commit -am "Adding cutoff method to String"
+  Created commit 670e353: Adding cutoff method to string
+   1 files changed, 15 insertions(+), 1 deletions(-)
+
+$ git checkout master
+  Switched to branch "master"
+
+$ git merge fixes
+  Updating e53ac7a..670e353
+  Fast forward
+   lib/jekyll/core_ext.rb |   16 +++++++++++++++-
+    1 files changed, 15 insertions(+), 1 deletions(-)
+
+ +Das war's! Mit @git branch -d fixes@ entfernst du den Branch. Da es so einfach ist, einen Branch zu erstellen und damit zu arbeiten, ist die Einbindung dieses Prozesses in den Arbeitsablauf sinnvoll. "Jos Susser":http://blog.hasmanythrough.com schrieb einen großartigen Beitrag darüber, wie er "Branches bei seiner Arbeit verwendet":http://blog.hasmanythrough.com/2008/12/18/agile-git-and-the-story-branch-pattern + +Es ist wirklich ein einfaches Beispiel eines fast-forward Merges. Aber das ist nicht immer so. Lass uns durch eine Änderung gehen, die ich in der selben Zeile der Datei in beiden Branches, Master und dem neuen Branch, gemacht habe. Schauen wir, wie Git darauf reagiert: + +
+$ vim lib/jekyll/core.rb
+
+$ git commit -am "Causing a merge on purpose"
+  Created commit 8aba87e: Causing a merge on purpose
+   1 files changed, 2 insertions(+), 2 deletions(-)
+
+$ git checkout -b conflicts
+
+$ vim lib/jekyll/core.rb
+
+$ git commit -am "Changing cutoff default"
+  Created commit 6041ddd: Changing cutoff default
+   1 files changed, 1 insertions(+), 1 deletions(-)
+
+$ git checkout master
+  Switched to branch "master"
+
+$ git merge conflicts
+  Auto-merged lib/jekyll/core_ext.rb
+  CONFLICT (content): Merge conflict in lib/jekyll/core_ext.rb
+  Automatic merge failed; fix conflicts and then commit the result.
+
+ +Die geöffnete Datei offenbart uns, dass Git uns die Unterschiede der Versionen in diesem Stück Text zeigt: + +p=. !/images/conflicts.png! + +@git status@ sollte noch unseren Konflikt anzeigen. Wir wollen die Änderung meiner neuen Version behalten und löschen einfach die Zeilen, die Git dort eingefügt hat und die alte Version. Die Datei mit @add@ und @commit@ normal behandeln und die Zusammenführung ist aufgelöst! + +
+$ git status
+  # On branch master
+  #
+  # Changed but not updated:
+  #   (use "git add ..." to update what will be committed)
+  #
+  # unmerged:   lib/jekyll/core_ext.rb
+  #
+
+$ vim lib/jekyll/core.rb
+
+$ git commit -am "Fixing conflict!"
+  Created commit 9c8e9fd: Fixing conflict!
+
+ +Damit entsteht ein besonderer Commit, der zwei Eltern-Commits hat, jeweils von den Branches, die zusammengeführt wurden: + +
+$ git show HEAD
+  commit 9c8e9fd335381fe6a97708f7b3cd1d5acf670d2d
+  Merge: 8aba87e... 6041ddd...
+  Author: Nick Quaranto 
+  Date:   Sun Jan 25 13:22:03 2009 -0500
+
+      Fixing conflict!
+
+ +Künftige Tips werden Helferwerkzeuge für diesen Prozess abdecken, wie "git-mergetool":http://www.kernel.org/pub/software/scm/git/docs/git-mergetool.html und @gitk --merge@. Wenn du ein gutes Tutorial dazu oder andere Arten der Zusammenführung kennst, "schicke uns einen Tip!":http://de.gitready.com/submit.html Schaue dir in der Zwischenzeit "Scott Chacons Gitcast zu diesem Thema an":http://gitcasts.com/posts/branching-and-merging oder lies den "Git Community Book's guide,":http://book.git-scm.com/3_basic_branching_and_merging.html wenn du mehr Informationen zu diesem Thema möchtest. + diff --git a/_posts/2009-01-26-text-based-graph.textile b/_posts/2009-01-26-text-based-graph.textile new file mode 100644 index 0000000..ac35fa7 --- /dev/null +++ b/_posts/2009-01-26-text-based-graph.textile @@ -0,0 +1,21 @@ +--- +layout: post +title: Text basierte Graphen +category: intermediate +published: true +--- + +Heute gibt es nur einen kurzen, aber interessanten Tip zu @git log --graph@. Wenn du verwirrt darüber bist, wo Branches hinführen oder wie Merges funktioniert haben und entweder zu faul bist, @gitk@, @gitx@ oder den "GitHub Network Graph": zu starten, so kannst du eine wirklich einfache und schnelle graphische Repräsentation deiner Commits erhalten. + +@git log --graph@ produziert das folgende Bild für meinen Clone des "jekyll":http://github.com/qrush/jekyll Repositories, das Änderungen des gestrigen Beitrags "Branchen und Mergen":http://de.gitready.com/beginner/2009/01/25/branching-and-merging.html aufweist, die noch nicht hochgeladen worden sind. In dieser Form ist die Ausgabe allerdings noch nicht sehr hilfreich: + +p=. !/images/graphfail.png! + +Lass uns das mit @git log --graph --pretty=oneline --abbrev-commit@ ein wenig schlanker gestalten, so dass wir die Commits komprimiert erhalten und nur 7 Zeichen des SHA1 angezeigt werden: + +p=. !/images/graph.png! + +Viel besser! Natürlich "gibt es eine ganze Reihe von Möglichkeiten zur graphischen Darstellung des Repositories.":http://gitready.com/intermediate/2009/01/13/visualizing-your-repo.html + +*UPDATE:* Den Befehl gibt es nur in den Git-Versionen 1.5.6 und aufwärts. + diff --git a/_posts/2009-01-27-installing-git.textile b/_posts/2009-01-27-installing-git.textile new file mode 100644 index 0000000..d1154ba --- /dev/null +++ b/_posts/2009-01-27-installing-git.textile @@ -0,0 +1,34 @@ +--- +layout: post +title: Git installieren +category: beginner +published: true +--- + +Das ist wahrscheinlich der grundlegendste Tipp: Git installieren. Es stellt sich heraus, dass die Verwendung von Git auf deinem System einfacher ist, als gedacht. Dieser Tipp wird kontinuierlich mit den neuesten und einfachsten Arten der Installation von Git auf deinem Lieblingsbestriebssystem aktualisiert. + +Falls die Liste keine Anleitung für dein Lieblingsbetriebssystem aufführt, Links veraltet sind oder du einen einfacheren Weg kennst, teile es uns in den Kommentaren mit! Lass uns auch wissen, wenn du Schwierigkeiten beim Installieren oder Kompilieren von Git hast. + +p=. "!http://farm4.static.flickr.com/3047/2754478731_6cac6d30a8_m.jpg!":http://flickr.com/photos/15708236@N07/2754478731/ + +*Windows* + +Ja, es funktioniert. Es gibt eine Reihe von großartigen Anleitungen, aber "nathanj's":http://github.com/nathanj "Illustrated Guide to Git on Windows":http://nathanj.github.com/gitguide/ ist einfach die Beste. Die Anleitung beschreibt, wie man auf dem System beginnt. Du kannst mit dem Download von "Git on MSys":http://code.google.com/p/msysgit/ anfangen. Eine andere Möglichkeit für Windows ist das "Kompilieren der Quellen":http://techblogging.wordpress.com/2008/04/11/compiling-and-installing-git-on-windows-under-cygwin/ mit "Cygwin":http://www.cygwin.com/. + +*OSX* + +Installere "MacPorts":http://macports.org auf 10.4 (Tiger) und führe @sudo port install git-core@ aus. Du kannst Git auch "manuell aus den Quellen kompilieren, falls das nicht funktioniert.":http://larrytheliquid.com/2007/12/29/compiling-git-and-git-svn-on-osx-tiger/ + +Dank des "Git OSX Installer":http://code.google.com/p/git-osx-installer/ Projekts läuft die Installation auf 10.5 (Leopard) um einiges einfacher ab. Wähle einfach die aktuellste Git-Version für deine CPU Architektur aus und du bist fertig. + +*Linux* + +Die Installation auf deiner Lieblingsdistribution ist recht einfach: + +p=. @apt-get install git-core@ +oder +@yum install git-core@ + +Für das Kompilieren aus den Quellen auf Ubuntu, hat "Chris Olson":http://chrisolsen.org eine "schöne Anleitung":http://chrisolsen.org/2008/03/10/installing-git-on-ubuntu/ erstellt. + +Schau im "Git Community Book":http://book.git-scm.com/2_installing_git.html für weitere Optionen nach oder lies im "GitWiki":http://git.or.cz/gitwiki/Installation weiter. diff --git a/_posts/2009-01-28-zsh-git-status.textile b/_posts/2009-01-28-zsh-git-status.textile new file mode 100644 index 0000000..86b2708 --- /dev/null +++ b/_posts/2009-01-28-zsh-git-status.textile @@ -0,0 +1,22 @@ +--- +layout: post +title: zsh Git Status +category: advanced +published: true +--- + +Du kannst dir den Status natürlich im "Bash Prompt":http://de.gitready.com/advanced/2009/01/23/bash-git-status.html anzeigen lassen. Aber das ist nicht einzige Option für die Shell! "ZSH":http://www.zsh.org/ oder die "Z Shell":http://de.wikipedia.org/wiki/Zsh ist eine andere beliebte Kommandozeile, die von vielen Entwicklern verwendet wird. Und es gibt eine ganze Reihe an Scripten, die den Repository Status schnell und einfach auf deine Shell bringen. + +"Joshua Corbin":http://github.com/jcorbin hat ein paar Scripte unter "zsh-git":http://github.com/jcorbin/zsh-git zusammengefaßt, die eine großartige Mischung von Farben und Informationen über dein Repository zusammentragen. Die Grundlagen werden auf der "Projektwebsite":http://www.wunjo.org/zsh-git/ erläutert und die Bilder machen sehr viel Spaß. + +Die Shell sieht standardmäßig so aus. Eine Fülle von Farben, die sogar beide Seiten des Bildschirms nutzen. In einem Repository ohne Änderungen werden der Branch-Name angezeigt und wohin der HEAD aktuell zeigt: + +p=. !/images/zsh-normal.png! + +Sobald eine Änderung gemacht wurde, erscheint ein ! (@git status@ wird ausgeführt, weil der Autor nur schwer mit Gewohnheiten brechen kann). Werden ungetrackte Dateien erzeugt, wird ein ? im Prompt hinzugefügt. Hinzugefügte Daten schreiben ein + auf den Prompt. Wenn du einen Branch verfolgst, wirst du benachrichtigt, sobald du mit den Commits voraus eilst. + +p=. !/images/zsh-workflow.png! + +Wenn du nach einer mehr DIY Version suchst, bietet "Bart Trojanowski":http://www.jukie.net/~bart ein schönes "Tutorial zum Hinzufügen des Branch Status":http://www.jukie.net/~bart/blog/20071219221358, das einfach erweitert werden kann. Wenn du nach einem weiteren einfachen ZSH Setup suchst, könnten dir "zshkit":http://github.com/mattfoster/zshkit/tree/master und seine verschiedenen Forks Spaß bereiten. Sie sind mit ausreichenden Hilfebefehlen ausgestattet. + +Wie immer, wenn du andere zsh Scripte oder andere Shells benutzt, die ihren eigenen Tipp verdienen, "reiche einen Tipp ein!":http://de.gitready.com/submit.html diff --git a/_posts/2009-01-29-exporting-your-repository.textile b/_posts/2009-01-29-exporting-your-repository.textile new file mode 100644 index 0000000..69a4b6d --- /dev/null +++ b/_posts/2009-01-29-exporting-your-repository.textile @@ -0,0 +1,30 @@ +--- +layout: post +title: Dein Repository exportieren +category: intermediate +published: true +--- + +Es gab bereits einen Tip zum Thema "Änderungen verteilen":http://de.gitready.com/intermediate/2009/01/24/sharing-your-changes.html, der allerdings die gesamte Repository-Geschichte beinhaltete. Was ist, wenn du eine bestimmte Änderung exportieren möchtest? Oder nur ein Verzeichnis? Was ist, wenn du ein Archiv deines Repositorys für ein Backup anfertigen möchtest? Keine Sorge, Git kann all das und noch mehr. Danke an "Stack Overflow":http://stackoverflow.com/questions/160608/how-to-do-a-git-export-like-svn-export für die hilfreichen Hinweise zu diesem Beitrag. + +Für ein schnelles Backup deines Repositorys hilft dir ein @git archive@. Wenn du eine ZIP-Datei für deine Repository-Dateien anlegen möchtest: + +@git archive HEAD --format=zip > archive.zip@ + +Der Archivieren-Befehl packt Repositories gewöhnlich in Tarballs, so dass du sie einfach in dein Lieblingskomprimierungsprogramm weiterreichen kannst: + +@git archive HEAD | gzip > archive.tar.gz@ + +Du kannst auch ein entferntes Repository archivieren, indem du die @--remote=@ Option verwendest. Beachte allerdings, dass das nicht für entfernte GitHub Repositories funktioniert. Hierfür wird "der Download-Button empfohlen.":http://groups.google.com/group/github/browse_thread/thread/cfcbcb1dc5f41f16 Mit anderen entfernten Repositories sollte das allerdings prima funktionieren. Lies die "Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-archive.html, wenn es Probleme gibt. + +Was ist, wenn du eine komprimierte Variante von Dateien möchtest? Dank des @checkout-index@ Befehls ist das ebenfalls einfach möglich. Grundsätzlich kopiert der Befehl alles im Index in ein anderes Verzeichnis. Dein Repository exportieren würde bedeuten: + +@git checkout-index -f -a --prefix=/path/to/folder/@ + +Die @-f@ Option überschreibt Dateien und die @-a@ beinhaltet alle Dateien und Verzeichnisse. Vergiß bitte nicht den abschließenden Schrägstrich bei der @--prefix@ Option. Er ist sehr wichtig! Weglassen läßt den Befehl glauben, du möchtest stattdessen jeden Dateinamen mit diesem Präfix auswählen. + +Wenn du nur eine bestimmte Datei oder ein bestimmtes Verzeichnis exportieren möchtest (in diesem Fall alles im bin/ Verzeichnis und die README): + +@git checkout-index -f --prefix=/path/to/folder/ bin/* README.textile@ + +Sehr schön! Du kannst diesen Befehl auch mit @find@ verketten, wenn du beispielsweise alle Header-Dateien exportieren möchtest. Schau dir die "checkout-index Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-checkout-index.html an. "Daniel Schierbeck":http://github.com/dasch hat diesen Prozess in kleine Scripte namens "git-export":http://github.com/dasch/git-export/tree zusammengefaßt, die einen Blick wert sind, wenn du sie öfters benutzt. diff --git a/_posts/2009-01-30-finding-what-has-been-changed.textile b/_posts/2009-01-30-finding-what-has-been-changed.textile new file mode 100644 index 0000000..b526a91 --- /dev/null +++ b/_posts/2009-01-30-finding-what-has-been-changed.textile @@ -0,0 +1,35 @@ +--- +layout: post +title: Finden, was sich geändert hat +category: intermediate +published: true +--- + +Häufig möchtest du einfach sehen, was sich während deiner Arbeit verändert hat. Vielleicht bist gerade etwas Essen gegangen und hast kurzzeitig vergessen, woran du gearbeitet hast, oder du möchtest überprüfen, was mit dem neuesten Commit hinzugefügt wird. Es gibt ein paar Git-Befehle, die dir damit helfen und einfach anzeigen, was geändert wurde. + +Die wahrscheinlich einfachste Möglichkeit ist ein @git diff@. Es zeigt die Zeilen an, die in deinem Arbeitsverzeichnis im Vergleich zum @HEAD@ geändert wurden. Die Veränderung einer Zeile in der README würde folgende Ausgabe erzeugen: + +p=. !/images/diff.png! + +Sofern deine Farboptionen eingeschalten sind, sollte sehr einfach zu sehen sein, welche Zeilen hinzugefügt, verändert uoder entfernt wurden. Es gibt einen Haufen anderer Optionen für diesen Befehl, aber ich werde sie und andere Diff-relevanten Helferlein in künftigen Tipps behandeln. + +@git diff@ vergleicht die "Staging Area":http://de.gitready.com/beginner/2009/01/18/the-staging-area.html und den letzten Commit miteinander. Vielleicht möchtest du aber auch sehen, welche Dateien im letzten Commit geändert wurden. Du könntest mit ein paar "Log Optionen":http://de.gitready.com/advanced/2009/01/20/bend-logs-to-your-will.html herumspielen oder @git whatchanged@ benutzen. Die Abkürzung zeigt dir die Commit-Nachricht, Autoreninformationen und druckt dir exakt aus, welche Dateien von dem Änderungssatz berührt wurden. Die Änderungen im letzten Commit: + +
+$ git whatchanged -n 1
+  commit 698192122d725da2bc79f273571d91dba8b645a8
+  Author: Nick Quaranto 
+  Date:   Wed Jan 28 09:22:46 2009 -0500
+
+      Adding support for setting post categories through YAML 
+      if not specified by directory structure
+
+      :100644 100644 92e4ce1... de43f33... M  .gitignore
+      :100644 100644 0706818... 81213b3... M  lib/jekyll/post.rb
+      :100644 100644 9aabcdd... 611d6d6... M  test/helper.rb
+      :100644 100644 56e5e42... 373545d... M  test/test_generated_site.rb
+      :100644 100644 713eec0... 202ea55... M  test/test_post.rb
+      :100644 100644 03bf166... 7bcf6de... M  test/test_site.rb
+
+ +Natürlich gibt es reichlich andere Optionen für diesen Befehl in der "Manpage.":http://www.kernel.org/pub/software/scm/git/docs/git-whatchanged.html Wenn du andere gute Ideen oder Wege für das Herausfinden von Änderungen im Repository kennst, lass sie uns wissen! diff --git a/_posts/2009-01-31-intro-to-rebase.textile b/_posts/2009-01-31-intro-to-rebase.textile new file mode 100644 index 0000000..5bfcc41 --- /dev/null +++ b/_posts/2009-01-31-intro-to-rebase.textile @@ -0,0 +1,48 @@ +--- +layout: post +title: Einführung in Rebase +category: intermediate +published: true +--- + +Gits "rebase":http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html Befehl ist für Einsteiger schwer zu verstehen und die "Beschreibung der Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html hilft nicht im Geringsten: + +
+git-rebase - Forward-port local commits to the updated upstream head +
+ +Ähhm, wie bitte? Das hilft vielleicht, wenn man weiß, wie Git arbeitet. Aber nicht im Geringsten, wenn du erst mit Git anfängst. Dank "Travis Swicegood":http://www.travisswicegood.com/ haben wir eine bessere Metapher: + +p=. "!http://farm4.static.flickr.com/3120/3174148419_51d09db6e5.jpg?v=0!":http://flickr.com/photos/hatrick/3174148419/ + +Ein Beil. Rebase hilft dabei, Commits aufzuteilen und sie in einer Weise zu zerschneiden, wie du sie servieren möchtest und platziert sie exakt an die Stelle, wo sie aus deiner Sicht hingehören. Mit dem Befehl kannst du tatsächlich die Geschichte deines Repositories umschreiben, sei es die Umordnung von Commits, das Zusammenführen in größere Commits, oder sei es das Ignorieren von Commits, wenn du es wünschst. + +Warum ist das hilfreich? Eine der verbreitetsten Anwendungsfälle ist die Arbeit an einem bestimmten Feature oder einer Fehlerbehebung in einem separaten Branch. Anstatt häßliche Merge Commits für jede Änderung zu erzeugen, die in den Master Branch überführt werden, könntest du eine große Änderung erzeugen und Rebase alles handhaben lassen. Ein anderer häufig vorkommender Fall für Rebase ist die Pflege von eigenen Änderungen für ein Projekt. Mit Merges wird die Repository-Geschichte mit Upstream-Commits und eigenen Commits vermischt. Mit Rebase wird das verhindert und somit das Repository in einem ausgewogenen Zustand gehalten. Wie das graphisch aussieht, zeigt das Ende von "Git for Computer Scientists":http://eagain.net/articles/git-for-computer-scientists/ oder "James Bowes' Beitrag zum Thema":http://jbowes.dangerouslyinc.com/2007/01/26/git-rebase-keeping-your-branches-current/. + +Ein einfaches Beispiel zeigt die Funktionsweise von Rebase. Ich lege einen neuen Branch für mein Feature an, entwickle daran herum und committe meine Änderungen. + +
+$ git checkout -b newfeature 
+Switched to a new branch "newfeature"
+
+[.. changed some files, made a few commits ..]
+
+$ git checkout master
+Switched to branch "master"
+
+[.. changed one file, committed ..]
+
+ +Die History im Repository sieht erstmal so aus (Screenshot von "gitx":http://gitx.frim.nl/): + +p=. !/images/rebase1.png! + +Jetzt möchte ich die Änderungen zurück in den Master-Branch überführen. Von dort könnte ich die Änderungen mit @git merge newfeature@ mergen. Wenn ich das so mache, sähe die Commit History wie folgendermaßen aus: + +p=. !/images/rebase2.png! + +Mit @git rebase newfeature@ sähe unsere History stattdessen so aus: + +p=. !/images/rebase3.png! + +Du siehst, wie alles viel sauberer und kompacter abschließt. Die Änderungen waren relativ einfach, Merge war wirklich einfach und erforderte keinerlei Arbeit. Zukünftige Tipps werden das Auflösen von Merge Problemen, die unterschiedlichen verfügbaren Merge-Algorithmen und natürlich den interaktiven Modus von Rebase behandeln. Dieser Beitrag vermittelt erstmal die Grundlagen zum Befehl selbst. Wenn du nützliche Tricks kennst, die du mit Rebase machst, "reiche einen Tip ein!":http://de.gitready.com/submit.html diff --git a/_posts/2009-02-01-push-to-only-bare-repositories.textile b/_posts/2009-02-01-push-to-only-bare-repositories.textile new file mode 100644 index 0000000..2c7981c --- /dev/null +++ b/_posts/2009-02-01-push-to-only-bare-repositories.textile @@ -0,0 +1,25 @@ +--- +layout: post +title: Push in ein Bare Repository +category: advanced +published: true +--- + +Typischerweise erlaubt dir Git, jede Art von Workflow aufzubauen. Anstatt zu sagen "du musst Git auf diese Art benutzen", erlaubt dir Git herauszufinden, welcher Workflow für dich und deine Organisation am besten ist. Aber wie in jedem System gibt es Ecken und Ösen, die dieser Tip behandelt. Lass uns als Erstes ein paar Definitionen zu Grunde legen: + +*Bare Repository": Ein Repository, das mit der @--bare@-Option geklont wurde. Es beinhaltet nur Dateien und Verzeichnisse im @.git@ Verzeichnis. +*Non-Bare Repositry": Ein normaler Klon, der ein Arbeitsverzeichnis mit ausgecheckten Dateien besitzt. + +Es gibt einen einfachen Weg, "deine Änderungen mit Git zu teilen,":http://de.gitready.com/intermediate/2009/01/24/sharing-your-changes.html aber manchmal möchtest du stattdessen "Push und Pull":http://de.gitready.com/beginner/2009/01/21/pushing-and-pulling.html gegenüber einem Repository ausführen. Wenn du deine Änderungen in ein Repository pushen möchtest, verwende nie ein non-bare Repository. Mit anderen Worten aus der "Git FAQ":https://git.wiki.kernel.org/index.php/GitFaq#Why_won.27t_I_see_changes_in_the_remote_repo_after_.22git_push.22.3F zitiert: + +
+A quick rule of thumb is to never push into a repository that has a work tree attached to it, until you know what you are doing. + +Eine kurze Daumenregel lautet, nie in ein Repository zu pushen, das mit einer Arbeitskopie verknüpft ist, bis du weißt, was du tust. +
+ +Die Lektion besteht darin, dass wenn du Änderungen pushen möchtest, erstelle einen Bare Repository Klon mit @git clone --bare@. Ab diesem Punkt kannst du die Änderungen mit "git daemon":http://www.kernel.org/pub/software/scm/git/docs/git-daemon.html bereit stellen, so dass andere Nutzer darauf zugreifen können. Das Hauptziel von Git ist es, *keine* Daten zu verlieren. Aus diesem Grunde wurde es so gebaut, dass es mit dem Pushen in non-bare Repositories unglücklich ist. + +Wenn du es dennoch aus irgendeinem Grund tun möchtest, gibt es Mechanismen, die dafür sorgen, dass du nicht versehentlich deine Daten verlierst. Sobald du in ein non-bare Repository gepusht hast, müsstest du deine Änderungen mit @git reset --hard HEAD@ wegwerfen und mit @git checkout -f@ deine gepushten Änderungen holen. Sogar wenn du etwas von deiner committeten Arbeit verloren hast, könntest du die Objekte mit @git reflog@ aus Gits Datenspeicher wiederherstellen. + +Jetzt, wo du über das Pushen in non-bare Repositories Bescheid weißt, wirst du hoffentlich den einfacheren Weg nehmen und einfach die Option @--bare@ benutzen. Wenn du das aus irgendeinem Grund nicht möchtest, weißt du jetzt, wie du es umgehen kannst. diff --git a/_posts/2009-02-02-push-and-delete-branches.textile b/_posts/2009-02-02-push-and-delete-branches.textile new file mode 100644 index 0000000..bedfa55 --- /dev/null +++ b/_posts/2009-02-02-push-and-delete-branches.textile @@ -0,0 +1,22 @@ +--- +layout: post +title: Push und Löschen von remote Branches +category: beginner +published: true +--- + +Die Aktionen Push in und Löschen von remote Branches führen viele Git-Anwender häufig durch. Aber einige (den Autor eingeschlossen) haben vergessen oder wissen einfach nicht, wie es geht. Hier ist die endgültige Anleitung. + +Sagen wir du hast "einen neuen Branch ausgecheckt":http://de.gitready.com/beginner/2009/01/25/branching-and-merging.html und ein paar Änderungen committed. Aber nun möchtest du diesen Branch mit einem anderen Entwickler teilen. Du kannst den Branch sehr einfach in einen remote Branch pushen: + +@git push origin newfeature@ + +@origin@ ist der Name des remote Repositories und @newfeature@ ist der Name des Branches, in den du pushen möchtest. Das ist bei weitem der einfachste Weg. Aber es gibt einen anderen Weg, wenn du eine andere Option suchst. "Geoff Lane":http://zorched.net hat ein "großartiges Tutorial":http://www.zorched.net/2008/04/14/start-a-new-branch-on-your-remote-git-repository/ geschrieben. Es beschreibt, wie eine Referenz in ein remote Repository gepushed, Änderungen abgeholt und der Branch getracked werden. + +Löschen ist auch eine sehr einfache Aufgabe: + +@git push origin :newfeature@ + +Der Befehl löscht den @newfeature@ Branch im remote Repository @origin@. Du musst den Branch selbst aber noch lokal mit @git branch -d newfeature@ löschen. + +Es gibt ein einfaches Script "git-publish-branch":http://git-wt-commit.rubyforge.org/#git-publish-branch genannt, erstellt von "William Morgan":http://all-thing.net/, das den Ablauf automatisiert. Es hilft dir, wenn du feststellst, dass du die Abläufe ständig wiederholst. Das Löschen von remote Branches fühlt sich damit etwas natürlicher an. Wenn du einfachere Wege für o.g. Aufgaben kennst, teile sie uns in den Kommentaren mit oder "sende uns einen Tip!":http://de.gitready.com/submit.html. diff --git a/_posts/2009-02-03-tagging.textile b/_posts/2009-02-03-tagging.textile new file mode 100644 index 0000000..1004432 --- /dev/null +++ b/_posts/2009-02-03-tagging.textile @@ -0,0 +1,64 @@ +--- +layout: post +title: Taggen +category: beginner +published: true +--- + +Taggen ist in Git eine großartige Art, um eine bestimmte Version des Codes zu kennzeichnen oder um aus irgendeinem Grund genau einen Commit in deiner Versionsgeschichte zu referenzieren. Dieser Beitrag behandelt die richtigen (und falschen) Wege, wie @git tag@ verwendet wird. + +Die wahrscheinlich beste Art einen Tag zu beschreiben ist eine kleine Klebezettelnotiz, die einen Commit kennzeichnet. Sie beinhaltet einen Namen, also etwas ähnliches wie @v1.0.0@ oder @production@, und auch eine Nachricht, wenn du möchtest. "Git for Computer Scientists":http://eagain.net/articles/git-for-computer-scientists/ visualisiert einen Tag folgendermaßen: + +p=. !http://eagain.net/articles/git-for-computer-scientists/git-storage.6.png! + +Wie wird ein Tag erzeugt? Einfach @git tag v1.0.0@, richtig? FALSCH. Das möchtest du *gewöhnlich* nicht tun. Einige Leute meinen, dass dieser Befehl "standardmäßig das Falsche macht":http://www.rockstarprogrammer.org/post/2008/oct/16/git-tag-does-wrong-thing-default/. Ohne Argumente erzeugt @git tag@ einen "leichtgewichtigen" Tag, der im Grunde genommen "ein Branch ist, der sich nie bewegt":http://book.git-scm.com/3_git_tag.html. Leichtgewichtige Tags sind dennoch nützlich, zum Beispiel zum Markieren einer bekannten guten (oder schlechten) Version oder zum Markieren einer Reihe von Commits, die du in der Zukunft vielleicht verwenden möchtest. Nichts desto trotz, solltest du diese Art von Tags nicht in ein remote Repository pushen. + +Normalerweise übergibst du mindestens die Option @-a@, um ein unsigniertes Tag zu erzeugen, oder du signierst ein Tag mit deinem GPG-Schlüssel über die Option @-s@ oder @-u @. Sobald das erledigt ist, kannst du @git describe@ benutzen, um zu sehen, wieviele Commits du seit dem letzten oder dem genannten Tag erzeugt hast. "Git-fu":http://gitfu.wordpress.com/ hat eine "schöne Anleitung":http://gitfu.wordpress.com/2008/05/25/git-describe-great-another-way-to-refer-to-commits/ über die Verwendung dieses Befehls (und verdient auch einen eigenen Tip in der Zukunft!). + +Dann erstellen wir einfach mal einen neuen Tag und schauen uns an, wie wir ihn referenzieren können, sogar wenn einige Commits vorgenommen worden sind. Dann pushen wir den Tag in ein remote Repository. Es ist viel einfacher, als du denkst: + +
+$ git tag -a v1.0.0 -m "Creating the first official version."
+
+$ git show v1.0.0 
+  tag v1.0.0
+  Tagger: Nick Quaranto 
+  Date:   Tue Feb 3 20:37:45 2009 -0500
+
+  Creating the first official version.
+  commit a8d1b55c5d4bdec843d9942cabf1b678bc1d4eed
+  Merge: 00b9675... 1b487b8...
+  Author: Nick Quaranto 
+  Date:   Sun Nov 30 00:41:08 2008 -0500
+
+      Merge branch 'master' of git@github.com:qrush/config
+
+$ git describe --tags
+  v1.0.0
+
+$ touch test
+$ git add test
+$ git commit -am "Adding test files"
+  Created commit a7aafb8: Adding test files
+   0 files changed, 0 insertions(+), 0 deletions(-)
+    create mode 100644 test
+
+$ git describe --tags
+  v1.0.0-1-ga7aafb8
+
+$ git push --tags
+  Counting objects: 40, done.
+  Compressing objects: 100% (37/37), done.
+  Writing objects: 100% (40/40), 29.32 KiB, done.
+  Total 40 (delta 15), reused 9 (delta 2)
+  To git@github.com:qrush/config.git
+   * [new tag]         v1.0.0 -> v1.0.0
+
+ +Der zweite describe Befehl zeigt uns, dass wir einen Commit vor dem zuletzt vorgenommenen Tag sind. Das ist eine einfache Möglichkeit, um herauszufinden, wieviel Arbeit seit dem letzten Commit erledigt wurde. Die @--tags@ Option wurde hier verwendet, um auch die Tags zu pushen. Aber nur der eine Tag konnte mit @git push origin : v1.0.0@ gepushed werden. Auf GitHub (oder in deinem remote Repository) solltest du die übertragenen Tags sehen: + +p=. !/images/tag.png! + +Eine kleine Randnotiz, falls du deine übertragenen Tags verschieben oder umbenennen möchtest, macht es dir Git sehr schwer, dies zu veranlassen. Sieh in der "Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-tag.html#_on_re_tagging nach. Hier bekommst du eine Erklärung, warum es so kompliziert ist und mit Bedacht verwendet werden sollte. + +Wenn du einen einzigartigen Weg für die Integration von Tags in deinen Git-Workflow kennst, teile ihn uns in den Kommentaren mit oder "sende uns einen Tip, so dass andere davon lernen können!":http://de.gitready.com/submit.html diff --git a/_posts/2009-02-04-converting-from-svn.textile b/_posts/2009-02-04-converting-from-svn.textile new file mode 100644 index 0000000..6510a15 --- /dev/null +++ b/_posts/2009-02-04-converting-from-svn.textile @@ -0,0 +1,38 @@ +--- +layout: post +title: Konvertieren eines SVN-Repository +category: beginner +published: true +--- + +Du liest diesen Artikel wahrscheinlich aus mehreren Gründen: + +* Du bist ein langjähriger SVN-Benutzer und möchtest sehen, worum es bei Git geht. +* Du möchtest wissen, was für eine Qual der Wechsel zu Git ist. +* Du hasst SVN und möchtest wissen, was besser ist. + +Anstatt noch eine Anleitung zu der Masse der vorhandenen Artikel über das Thema beizutragen, habe ich mich für den einfachn Weg entschieden und eine Liste von großartigen Anleitungen über die Migration zu Git für jene zusammengestellt, die mit SVN vertraut sind. Wenn du noch weitere Links kennst füge sie in den Kommentaren hinzu und ich füge sie hier ein. + +*Anleitungen für einen Wechsel zu Git* +_Die Anleitungen beschreiben, wie unterschiedlich die beiden Versionskontrollsysteme sind und wie sie auf einem (meist) höheren Level funktionieren._ + +* "Git SVN Workflow":http://andy.delcambre.com/2008/03/04/git-svn-workflow.html +* "GitSvnComparsion":http://git.or.cz/gitwiki/GitSvnComparsion +* "An introduction to git-svn for Subversion/SVK users and deserters":http://utsl.gen.nz/talks/git-svn/intro.html + +*Anleitungen zu Befehlen* +_Die Anleitungen fokusieren sich auf das Lernen der Befehle, die Aktionen zwischen den beiden Systemen durchführen._ + +* "Git - SVN Crash Course":http://git.or.cz/course/svn.html +* "Howto use Git and svn together":http://flavio.castelli.name/howto_use_git_with_svn +* "git[-svn] in 30 minutes":http://michael-prokop.at/blog/2007/12/03/git-svn-in-30-minutes/ + +*Migrationsanleitungen* +_Diese Anleitungen zeigen auf, wie du deine History von SVN importieren kannst und wie du mit anderen Entwicklern zusammenarbeitest, die noch nicht von Git überzeugt sind._ + +* "Converting Subversion repositories to Git":http://weblog.redlinesoftware.com/2008/2/24/converting-subversion-repositories-to-git +* "Converting a Shared Subversion Repository to Git":http://notahat.com/posts/25 +* "How to convert from Subversion to Git":http://pauldowman.com/2008/07/26/how-to-convert-from-subversion-to-git/ +* "git-svn is a gateway drug":http://www.robbyonrails.com/articles/2008/04/10/git-svn-is-a-gateway-drug + +Tips zu git-svn sind immer noch mehr als nur willkommen. Seien es Konfigurationsoptionen, Bugs/Probleme, die dir begegnet sind, etc. "Schicke uns":/submit.html einfach deine Ideen! diff --git a/_posts/2009-02-05-bash-auto-completion.textile b/_posts/2009-02-05-bash-auto-completion.textile new file mode 100644 index 0000000..17bacec --- /dev/null +++ b/_posts/2009-02-05-bash-auto-completion.textile @@ -0,0 +1,24 @@ +--- +layout: post +title: Bash Auto-Vervollständigung +category: advanced +published: true +--- + +Dieser Tipp kommt vom ewig einfallsreichen "Brian Cardarella":http://cardarella.blogpost.com/, der die Quintessenz zum "Installieren und Einrichten der Auto-Vervollständigung mit Git (Englisch)":http://gist.github.com/58383 beschreibt. Sie basiert auf "Shawn O. Pierces":http://spearce.org Script zur Bash Vervollständigung. Was leistet das Script für dich? + +
+Die beinhaltenden Vervollständigungsroutinen bieten Unterstützung für: +* lokale und entfernte Branch-Namen +* lokale and entfernte Tag-Namen +* .git/remotes Dateinamen +* Git 'subcommands' +* Baumpfade innerhalb von 'ref:path/to/file' Ausdrücken +* allgemeine --Lang-Optionen +
+ +Die Installation ist wirklich einfach: Lade/wget/curl die Dateien herunter und lege sie in deinem Heimatverzeichnis ab. Editiere deine @.bash_profile@ Datei und schon bist du fertig. "Eric Goodwin":http://blog.ericgoodwin.com/ hat auch einen großartigen Artikel über "Download und Installation des Scripts":http://blog.ericgoodwin.com/2008/4/10/auto-completion-with-git geschrieben, falls du Git nicht aus den Quellen kompiliert und installiert hast. Er hat auch einen "fantastischen Artikel":http://blog.infinitered.com/entries/show/4 über die verschiedenen Startdateien der Bash gefunden, falls das für dich alles neu ist. + +Mac OS X Benutzer können die MacPorts zur Installation des Scripts verwenden. "Pratik Naik":http://m.onkey.org/2008/4/12/if-you-see-this hat eine einfache Art zur Installation, falls du die @+bash_completion@ Option verwendest. Wenn nicht, ist es wahrscheinlich einfacher deine aktuelle Version zu deaktivieren und sie mit der ausgewählten Option zu reinstallieren. + +Falls du dich mit dem Thema auf anderen Shells auskennst, einfach kommentieren oder einen "Tipp einreichen!":http://de.gitready.com/submit.html diff --git a/_posts/2009-02-06-helpful-command-aliases.textile b/_posts/2009-02-06-helpful-command-aliases.textile new file mode 100644 index 0000000..88b6587 --- /dev/null +++ b/_posts/2009-02-06-helpful-command-aliases.textile @@ -0,0 +1,46 @@ +--- +layout: post +title: Hilfreiche Befehlsaliase +category: intermediate +published: true +--- + +Das Hinzufügen von häufig verwendeten Befehlen als Aliase in deine @.gitconfig@ Datei vereinfacht dir dein Leben im Umgang mit Git. Es mag nicht ganz so elegant sein wie das Hinzufügen von Aliasen zur Shell, aber es funktioniert wenigstens über alle Shells hinweg und ist sehr einfach einzurichten. Das "Git Cheat Sheet":http://cheat.errtheblog.com/s/git schlägt vor, folgenden Block in deine Konfigurationsdatei einzufügen: + +
+[alias]
+  st = status
+  ci = commit
+  br = branch
+  co = checkout
+  df = diff
+  lg = log -p
+
+ +Sobald der Block in deine Konfigurationsdatei eingefügt wurde, sollte es sofort funktionieren: + +
+$ git st
+# On branch master
+# Untracked files:
+#   (use "git add ..." to include in what will be committed)
+#
+#  _posts/2009-02-06-helpful-command-aliases.textile
+nothing added to commit but untracked files present (use "git add" to track)
+
+ +Du kannst Aliase auch mit folgendem Befehl hinzufügen und sie stehen dann automatisch in der @.gitconfig@ Datei: + +
+$ git config –-global alias.rb rebase
+
+ +Für SVN-Konvertiten: Alex Soto hat ein paar Alias-Helfer vorgeschlagen, die bei der Interaktion mit Subversion-Repositories helfen: + +
+[alias]
+  spull = !git-svn fetch && git-svn rebase
+  spush = !git-svn dcommit
+
+ +Es gibt eine Menge anderer fortgeschrittener Befehle im "GitWiki":http://git.or.cz/gitwiki/Aliases. Wenn du Aliase hast, die für andere nützlich sein könnten, füge bitte einen Kommentar hinzu oder "reiche einen Tip ein":http://de.gitready.com/submit.html und sie werden hinzugefügt! diff --git a/_posts/2009-02-09-reflog-your-safety-net.textile b/_posts/2009-02-09-reflog-your-safety-net.textile new file mode 100644 index 0000000..e7d714b --- /dev/null +++ b/_posts/2009-02-09-reflog-your-safety-net.textile @@ -0,0 +1,54 @@ +--- +layout: post +title: reflog, dein Sicherheitsnetz +category: intermediate +published: true +--- + +Wir haben den "reflog":http://www.kernel.org/pub/software/scm/git/docs/git-reflog.html Befehl kurz in dem früheren Beitrag "Verlorene Commits wieder herstellen":http://de.gitready.com/advanced/2009/01/17/restoring-lost-commits.html behandelt. Er wurde aber bisher nie erklärt. Heute schauen wir uns an, wie man ihn als Sicherheitsnetz zum Wiederherstellen verwendet. + +p=. "!http://farm4.static.flickr.com/3462/3222479388_abcb084c1a.jpg?v=0!":http://flickr.com/photos/paradisecircus/3222479388/ + +Die Manpages zu diesem Befehl sind sehr knapp gehalten: + +
+git-reflog - Manage reflog information +
+ +Die Definition an späterer Stelle im Dokument ist ein wenig besser: + +
+Reflog is a mechanism to record when the tip of branches are updated. This command is to manage the information recorded in it. +
+ +Übersetzung: +
+Reflog ist ein Mechanismus, der sich den Aktualisierungszeitpunkt der Spitze eines Zweiges merkt. Der Befehl verwaltet die aufgezeichneten Informationen. +
+ +Jede unternommene Aktion in Git wird grundsätzlich im Reflog gespeichert. Git versucht äußerst stark keine Daten zu verlieren. Wenn du also denkst, etwas verloren zu haben, stehen die Chancen recht gut, dass du sie mit @git reflog@ wieder ausgraben kannst. Das bedeutet, der Befehl läßt sich als Sicherheitsnetz verwenden: Du brauchst dir also keine Gedanken darüber zu machen, dass ein Merge, ein Rebase oder eine andere Aktion deine Arbeit zerstört, weil du sie mit dem Befehl wieder finden kannst. + +Die gebräuchlichste Verwendung von @git reflog@ beläuft sich darin, dass du soeben ein @git reset@ durchgeführt und den @HEAD@ ein paar Commits zurück gesetzt hast. Aber leider brauchst du den Codeteil, den du im zweiten Commit zurück gelassen hast. Mist. Was nun? @git reflog@ wird wahrscheinlich ein Ergebnis der folgenden Art erzeugen: + +p=. !/images/reflog.png! + +Du siehst eine Liste von Übergaben, die Git noch in seinem Speicher hat. Die ersten 7 Zeichen sind der Anfang des SHA, gefolgt vom Commit-Pointer, der Aktion und der Nachricht. Es werden nicht nur Übergaben aufgelistet: Der Wechsel von Branches, Merges, Rebases und mehr werden angezeigt. Die wichtigen Teile sind der Pointer und der SHA-Hash. Sobald du den hast, kannst du die Änderung mit @git show@ anzeigen oder vielleicht ein @checkout@, @cherry-pick@ oder @merge@ durchführen, abhängig davon, wie du die Änderung in deine Historie zurück haben möchtest. + +Du kannst auch die @--all@ Option für detailliertere Informationen über verschiedene Branches und sogar den Stash verwenden: + +p=. !/images/reflog-all.png! + +Der Befehl wird auch zu einem anderen Zweck eingesetzt: Alte Einträge löschen, die du nicht mehr benötigst. Das passiert beim Platz sparen in deinem Repository oder vielleicht weil du ab und zu den Müll rausbringen möchtest. Du kannst einzelne Reflogs mit dem @delete@ Befehl beseitigen. Der @expire@ Befehl ist nützlicher, da ihm ein Datum übergeben werden kann. Es gibt den Zeitpunkt an, bis wohin Einträge gelöscht werden sollen. + +Ein Beispiel zum schnellen Zusammenpacken deines Repositories findet sich in "John Wiegley's":http://www.newartisans.com/blog/ Beitrag in "Diving into Git":http://www.newartisans.com/blog/2008/04/diving-into-git.html, wo er sein Repository mit den folgenden Befehlen komprimiert: + +
+$ git reflog expire --expire=1.minute refs/heads/master
+$ git fsck --unreachable      
+$ git prune                   
+$ git gc                      
+
+ +Die Befehlsabfolge entfernt alle Reflogs im Hauptzweig, die älter als eine Minute sind, findet und löscht alle Commits, die nicht mehr verwendet werden. Anschließend erfährt das gesamte Repository einen Großputz und wird weiter komprimiert. Dieser Vorgang könnte einen eigenen Beitrag vertragen, aber es ist wahrscheinlich besser, den enormen Nutzen eines Befehls in deinem Arbeitsablauf zu veranschaulichen. + +Schau in der "Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-reflog.html nach für weitere Optionen. Und wenn du weitere Verwendungsmöglichkeiten kennst, lass es uns wissen! diff --git a/_posts/2009-02-10-squashing-commits-with-rebase.textile b/_posts/2009-02-10-squashing-commits-with-rebase.textile new file mode 100644 index 0000000..a0c3ade --- /dev/null +++ b/_posts/2009-02-10-squashing-commits-with-rebase.textile @@ -0,0 +1,97 @@ +--- +layout: post +title: Commits mit Rebase vereinen +category: advanced +published: true +--- + +Der "Rebase-Befehl":http://de.gitready.com/intermediate/2009/01/31/intro-to-rebase.html hat ein paar großartige Optionen in seinem @--interactive@ (oder @-i@) Modus. Eine der wohl am weitesten verbreiteten Optionen ist das Zusammenführen/Vereinen oder "Squashen" von Commits. Es nimmt kleinere Commits und vereint sie zu größeren Commits. Das kann zum Beispiel nützlich sein, wenn du die Tagesarbeit zusammenfassen oder wenn du deine Änderungen anders paketieren möchtest. Im Folgenden wird beschrieben, wie das geht. + +p=. "!http://farm4.static.flickr.com/3073/2926413646_8e4a7b7db4.jpg?v=0!":http://flickr.com/photos/7552532@N07/2926413646/ + +*Vorsicht:* Führe die Aktion nur für Commits durch, die du noch nicht zu einem externen Repository geschickt hast. Wenn andere Entwickler ihre Arbeit auf der Basis deiner Commits aufbauen, die du aber ändern oder löschen wirst, können eine ganze Reihe von Konflikten auftreten. Schreibe deine History einfach nicht neu, sobald du sie mit anderen geteilt hast! + +Lass uns annehmen, du hast soeben ein paar kleine Commits vorgenommen und du möchtest daraus einen größeren Commit machen. Unsere Repository-History sieht derzeit ungefähr so aus: + +p=. !/images/squash1.png! + +Die letzten 4 Commits würden schöner aussehen, wenn sie zu einem zusammengefasst wären. Das machen wir jetzt, indem wir ein interaktives Rebase durchführen: + +
+$ git rebase -i HEAD~4
+
+pick 01d1124 Adding license
+pick 6340aaa Moving license into its own file
+pick ebfd367 Jekyll has become self-aware.
+pick 30e0ccb Changed the tagline in the binary, too.
+
+# Rebase 60709da..30e0ccb onto 60709da
+#
+# Commands:
+#  p, pick = use commit
+#  e, edit = use commit, but stop for amending
+#  s, squash = use commit, but meld into previous commit
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+# However, if you remove everything, the rebase will be aborted.
+#
+
+ +Ein paar Dinge passieren hier. Als erstes habe ich Git gesagt, dass es einen Rebase mit den letzten vier Commits machen soll, ausgehend vom @HEAD@, also @HEAD~4@. Git hat mir einen Editor mit dem obigen Text geöffnet und eine kleine Erklärung eingefügt, was ich nun machen kann. Nun stehen ein paar Optionen zur Verfügung, aber wir möchten vorerst alles in einen Commit zusammenführen. Ändere die ersten vier Zeilen der Datei folgendermaßen und das gewünschte Ergebnis wird erreicht: + +
+pick 01d1124 Adding license
+squash 6340aaa Moving license into its own file
+squash ebfd367 Jekyll has become self-aware.
+squash 30e0ccb Changed the tagline in the binary, too.
+
+ +Im Grunde genommen wird Git gesagt, alle vier Commits sollen in den ersten Commit in der Liste zusammenführt werden. Sobald das erledigt und gespeichert ist, kommt wieder ein Editor mit dem folgenden Inhalt: + +
+# This is a combination of 4 commits.
+# The first commit's message is:
+Adding license
+
+# This is the 2nd commit message:
+
+Moving license into its own file
+
+# This is the 3rd commit message:
+
+Jekyll has become self-aware.
+
+# This is the 4th commit message:
+
+Changed the tagline in the binary, too.
+
+# Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+# Explicit paths specified without -i nor -o; assuming --only paths...
+# Not currently on any branch.
+# Changes to be committed:
+#   (use "git reset HEAD ..." to unstage)
+#
+#	new file:   LICENSE
+#	modified:   README.textile
+#	modified:   Rakefile
+#	modified:   bin/jekyll
+#
+
+ +Weil wir mehrere Commits zu einem zusammenführen, erlaubt uns Git die Commitnachricht auf der Grundlage der im Prozess involvierten Commits zu ändern. Bearbeite die Nachricht, wie es dir gefällt, speichere und schließe den Editor. Jetzt sind deine Commits erfolgreich zusammengeführt, sie sind "squashed"! + +
+Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
+ 4 files changed, 27 insertions(+), 30 deletions(-)
+  create mode 100644 LICENSE
+	Successfully rebased and updated refs/heads/master.
+
+ +Und wenn du wieder in die History schaust... + +p=. !/images/squash2.png! + +Das war soweit relativ schmerzfrei. Wenn du während des Rebase auf Konflikte triffst, sind sie in der Regel recht einfach aufzulösen und Git führt dich so gut es kann durch. Die Grundlage besteht in der Auflösung des fraglichen Konflikts. @git add@ auf die Datei und dann ein @git rebase --continue@ setzt den Prozess fort. Natürlich bringt dich ein @git rebase --abort@ zurück zu deinem vorherigen Zustand, wenn du möchtest. Solltest du aus irgendeinem Grund während des Rebase einen Commit verloren haben, kannst du "reflog":http://de.gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html benutzen, um ihn wiederherzustellen. + +Es gibt eine ganze Reihe von anderen Nutzungsmöglichkeiten für @git rebase -i@, die noch nicht betrachtet wurden. Falls du eine kennst, die du mitteilen möchtest, "reiche einen Tip ein!":http://de.gitready.com/submit.html "GitCasts":http://gitcasts.com/ hat ein "schönes Video":http://gitcasts.com/posts/rebasing über den gesamten Prozess und behandelt ein paar komplexere Beispiele dieses Befehls. diff --git a/_posts/2009-02-11-pull-with-rebase.textile b/_posts/2009-02-11-pull-with-rebase.textile new file mode 100644 index 0000000..d071ba6 --- /dev/null +++ b/_posts/2009-02-11-pull-with-rebase.textile @@ -0,0 +1,60 @@ +--- +layout: post +title: Pull mit Rebase +category: advanced +published: true +--- + +Git-Anwender sind sich hoffentlich bewußt, dass ein @git pull@ ein @git fetch@ zum Herunterladen der Daten aus einem entfernten Repository durchführt und dann @git merge@ aufruft, um die empfangenen Änderungen mit dem aktuellen Arbeitszweig zusammenzuführen. Das mag jedoch nicht immer die beste Wahl sein. Du kannst die Änderungen ebenso mittels "rebase":http://de.gitready.com/intermediate/2009/01/31/intro-to-rebase.html einpflegen, das um ein vielfaches sauberer ist. Das kann einfach durch die Option @--rebase@ des Pull-Befehls erreicht werden, ungefähr so: + +@git pull --rebase @ + +Aber warum ist das nützlich? Manchmal ist es einfacher, den Inhalt von Upstream eben nicht einzupflegen, sondern deine Arbeit auf die eingehenden Änderungen erneut anzuwenden. Für Langzeitänderungen ist ein Merge wahrscheinlich besser. Aber für kleinere Änderungen wird die Historie mittels Rebase sauberer bleiben. Nehmen wir an, ich möchte Rebase anstelle von Merge verwenden, um ein paar Upstream-Änderungen aus dem Hauptrepository von "jekyll":http://github.com/mojombo/jekyll in meinen "Fork":http://github.com/qrush/jekyll zu übertragen. Das Repository sieht aktuell ungefähr so aus: + +p=. !/images/pull1.png! + +Zu Demonstrationszwecken habe ich mojombos Master ausgecheckt, so dass du sehen kannst, dass es hier ein paar Commits gibt, die mein Master-Zweig nicht hat: (Die drei Commits, die bei 'mojombo' beginnen und bis 'mojombo/master' gehen, sind nicht in der obigen Grafik) + +p=. !/images/pull2.png! + +So, holen wir die Änderungen mit Rebase von mojombos entferntem Repository in seinem Master-Zweig: (Warnungen wurden entfernt) + +
+$ git pull --rebase mojombo master
+From git://github.com/mojombo/jekyll
+ * branch            master     -> FETCH_HEAD
+ First, rewinding head to replay your work on top of it...
+
+Applying: Making rake test happy on 1.8.7
+Applying: Starting on yaml categories
+Applying: Adding support for setting post categories...
+Applying: Added publish flag to posts, not preventing... 
+Applying: Making sure that posts flagged as published...
+Applying: Adding explanations for new YAML front matter...
+Applying: Removing some bad formatting in the README
+
+ +Jetzt schauen wir wieder auf die Historie des Master-Zweigs: + +p=. !/images/pull3.png! + +Du kannst sehen, dass meine Arbeit (alles von der Bezeichnung 'mojombo' und aufwärts) schon auf der Arbeit in mojombos Repository aufsetzt. Großartig! Was ist aber der Unterschied zu einem normalen Pull? Wir finden es heraus. + +
+$ git reset --hard origin/master
+HEAD is now at 60709da Removing some bad formatting in the README
+
+$ git pull mojombo master
+From git://github.com/mojombo/jekyll
+ * branch            master     -> FETCH_HEAD
+Merge made by recursive.
+ VERSION.yml    |    2 +-
+ jekyll.gemspec |    7 ++++---
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+ +Zuerst habe ich das Repository zu seinem ursprünglichen Zustand zurück gesetzt und dann habe ich einen normalen Pull ausgeführt. Da es ein Merge ist, erscheint es auch als solcher: + +p=. !/images/pull4.png! + +Du kannst nun sehen, dass die Upstream-Änderungen übernommen worden sind. Ein neuer Commit verdeutlicht, dass ein Merge stattgefunden hat. Manchmal möchte man die Historie genau so gestalten, aber eben nicht immer. Es ist dir überlassen, wie du deine Historie aufbaust. Wenn du immer Rebase anstatt Merge mit @git pull@ ausführen möchtest, hilft dir dieser "Tip":http://tumbl.strelau.net/post/47338904/git-pull-rebase-by-default weiter. Er zeigt, welche Konfigurationsoptionen gesetzt werden müssen. diff --git a/_posts/2009-02-12-easily-fetching-upstream-changes.textile b/_posts/2009-02-12-easily-fetching-upstream-changes.textile new file mode 100644 index 0000000..d00f8cf --- /dev/null +++ b/_posts/2009-02-12-easily-fetching-upstream-changes.textile @@ -0,0 +1,27 @@ +--- +layout: post +title: Upstream-Änderungen einfach herunterladen +category: intermediate +published: true +--- + +Dieser Tip ist von "Dav Glass":http://blog.davglass.com/, dessen Arbeit an "YUI":http://developer.yahoo.com/yui/ auf "GitHub":http://github.com/yui häufig Commits erfordert. Also hat er sich einen "hilfreichen alias":http://gitready.com/intermediate/2009/02/06/helpful-command-aliases.html erstellt, mit dem er Änderungen einfach zusammenführen kann. + +Zunächst hat er ein konsistentes Namensschema für sein entferntes Upstream-Repository festgelegt: + +@git remote add upstream git://github.com/user/repo.git@ + +Das wirfst du dann in deine @.gitconfig@ und schon bist du fertig: + +
+[alias]
+  pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
+
+ +@git pu@ zieht alle neuesten Änderungen von beiden entfernten Repositories und führt sie zusammen. + +Was ist daran aber anders als ein @git pull upstream master@? Es werden Änderungen von zwei verschiedenen Quellen zusammengeführt: Der eigene Fork und das Upstream-Repository. Ein "pull":http://de.gitready.com/beginner/2009/01/21/pushing-and-pulling.html zieht für gewöhnlich nur Änderungen von einer Quelle. Falls du verwirrt bist, wie das funktioniert, schau im Abschnitt "History" von "Git for Computer Scientists":http://eagain.net/articles/git-for-computer-scientists/#history vorbei. Dort zeigen dir ein paar Schaubilder, wie der Fetch- und Merge-Prozess funktionieren. + +Natürlich gibt es viele unterschiedliche Wege, mit dem Problem umzugehen. Du könntest beispielsweise "rebase":http://de.gitready.com/intermediate/2009/01/31/intro-to-rebase.html oder sogar "Pull mit Rebase":http://de.gitready.com/advanced/2009/02/11/pull-with-rebase.html anstatt das Zusammenführen (Merge) verwenden. Es hängt alles davon ab, wie du deine Repository-History organisieren möchtest und was für dich am einfachsten ist. + +Wenn du Aliase oder Vorschläge hast, um diesen Prozess einfacher zu gestalten, lass es uns gerne wissen! diff --git a/_posts/2009-02-13-list-remote-branches.textile b/_posts/2009-02-13-list-remote-branches.textile new file mode 100644 index 0000000..fac7a05 --- /dev/null +++ b/_posts/2009-02-13-list-remote-branches.textile @@ -0,0 +1,62 @@ +--- +layout: post +title: Remote Branches auflisten +category: intermediate +published: true +--- + +Manchmal möchtest du herausfinden, welche "Branches":http://de.gitready.com/beginner/2009/01/25/branching-and-merging.html in deinem entfernten Repository existieren, so dass du sie herunterladen, auschecken und mit deinen lokalen Branches zusammenführen kannst. Wenn du "GitHub":http://github.com oder "gitweb":http://git.or.cz/gitwiki/Gitweb zum Hosten deines Repositories verwendest, ist es im Normalfall recht einfach, die Namen der Branches zu identifizieren. Aber wenn du sie allgemein oder für Scripte benötigst, ist es schon nicht mehr so klar. + +p=. "!http://farm4.static.flickr.com/3163/3100342708_b12c4a36d6.jpg!":http://flickr.com/photos/joiseyshowaa/3100342708/ + +*UPDATE:* Die Kommentare haben mich ein wenig erleuchtet... Es scheint immer mehrere Wege zu geben, das Pferd mit Git zu zäumen. Der einfacheste Weg ist es, einfach die verschiedenen Optionen des @git branch@ Befehls zu verwenden. @-a@ zeigt alle lokalen und entfernten Branches an, wohingegen @-r@ nur die entfernten Branches anzeigt. + +
+$ git branch
+* master
+
+$ git branch -a
+* master
+  origin/1-2-stable
+  origin/2-0-stable
+  origin/2-1-stable
+  origin/2-2-stable
+  origin/3-0-unstable
+  origin/HEAD
+  origin/master
+
+$ git branch -r
+  origin/1-2-stable
+  origin/2-0-stable
+  origin/2-1-stable
+  origin/2-2-stable
+  origin/3-0-unstable
+  origin/HEAD
+  origin/master
+
+ +Sobald man den Namen des Branches kennt, ist es sehr einfach, ihn "auszuchecken":http://de.gitready.com/intermediate/2009/01/09/checkout-remote-tracked-branch.html. Falls du die Farboptionen aktiviert hast, werden noch nicht heruntergeladene Branches in rot aufgelistet. + +Es gibt noch einen anderen Weg herauszufinden, welche Branches sich im entfernten Repository befinden, indem die entsprechenden remote Befehle @git remote@ und @git ls-remote@ verwendet werden. Ersterer zeigt eine Reihe von Informationen über das entfernte Repository im Allgemeinen an und in welcher Beziehung sie zu deinem lokalen Repository stehen. Der letztere Befehl listet einfach nur alle Referenzen zu Branches und Tags auf, die er kennt. + +
+$ git remote show origin
+* remote origin
+  URL: git://github.com/rails/rails.git
+  Remote branch merged with 'git pull' while on branch master
+    master
+  Tracked remote branches
+    1-2-stable 2-0-stable 2-1-stable 2-2-stable 3-0-unstable master
+
+$ git ls-remote --heads origin
+5b3f7563ae1b4a7160fda7fe34240d40c5777dcd  refs/heads/1-2-stable
+71926912a127da29530520d435c83c48778ac2b2  refs/heads/2-0-stable
+2b158543247a150e8ec568becf360e7376f8ab84  refs/heads/2-1-stable
+b0792a3e7be88e3060af19bab01cd3d26d347e4c  refs/heads/2-2-stable
+d6b9f8410c990b3d68d1970f1461a1d385d098d7  refs/heads/3-0-unstable
+f04346d8b999476113d5e5a30661e07899e3ff80  refs/heads/master
+
+ +Der @ls-remote@ Befehl gibt den SHA1 Hash des neuesten Commits für die jeweilige Referenz zurück, so dass es sehr einfach zu parsen ist und der exakte Commit für Scripte verwendet werden kann. Die Option @--heads@ listet nur die Namen der Branches auf, weil der Befehl auch Tags auflisten kann. + +Falls du andere Verwendungsmöglichkeiten für diese Befehle oder einfache Wege zum Herausfinden der Branches in entfernten Repositories kennst, kommentiere das einfach! diff --git a/_posts/2009-02-16-convert-git-svn-tag-branches-to-real-tags.textile b/_posts/2009-02-16-convert-git-svn-tag-branches-to-real-tags.textile new file mode 100644 index 0000000..752a618 --- /dev/null +++ b/_posts/2009-02-16-convert-git-svn-tag-branches-to-real-tags.textile @@ -0,0 +1,34 @@ +--- +layout: post +title: git-svn Tag-Branches in richtige Tags umwandeln +category: advanced +published: true +--- + +Danke an "Alexis Modin":http://beardedmagnum.com für seinen Beitrag zu diesem Tip. Der ursprüngliche Artikel befindet sich "hier":http://beardedmagnum.com/2009/02/15/converting-git-svn-tag-branches-to-real-tags/. + +Alexis fand heraus, dass Tags während des Umwandlungsprozesses von Subversion zu Git durcheinander gebracht werden und als Tag-Branches erscheinen, anstatt als umgewandelte Tags. Das kann ziemlich lästig werden, insbesondere wenn mit @git branch@ ein Haufen anderer Branches wie zum Beispiel @tag/1.2@ auftaucht. Ein bißchen Scripting und Git-Magie räumt das einfach auf. + +Alexis folgte dem Standardprozess zum Umwandeln eines SVN Repositories: + +
+$ mkdir rails
+$ cd rails 
+$ git svn init -t tags -b branches -T trunk 
+Initialized empty Git repository in .git/
+$ git svn fetch
+
+ +Als nächstes nahm er ein kleines Script zu Hilfe, mit dem alle Tag-Branches in "richtige Tags":http://de.gitready.com/beginner/2009/02/03/tagging.html umgewandelt werden. Des Weiteren wird sichergestellt, dass die Tag-Branches anständig gelöscht werden. + +
+$ git-for-each-ref refs/remotes/origin/tags | cut -d / -f 5- |
+while read ref
+do
+git tag -a "$ref" -m"say farewell to SVN" "refs/remotes/origin/tags/$ref"
+git push origin ":refs/heads/tags/$ref"
+git push origin tag "$ref"
+done
+
+ +Wenn du Scripte erstellt hast, die das Umwandeln von anderen SCMs nach Git unterstützen, teile es uns in den Kommentaren mit oder "sende uns deinen eigenen Tip!":http://de.gitready.com/submit.html diff --git a/_posts/2009-02-17-how-git-stores-your-data.textile b/_posts/2009-02-17-how-git-stores-your-data.textile new file mode 100644 index 0000000..1b832b9 --- /dev/null +++ b/_posts/2009-02-17-how-git-stores-your-data.textile @@ -0,0 +1,31 @@ +--- +layout: post +title: Wie Git deine Daten speichert +category: beginner +--- + +Das ist eine sehr breite Übersicht über die Funktionsweise des Git Objektmodells, hauptsächlich basierend auf dem "Git Community Book":http://book.git-scm.com/1_the_git_object_model.html. Zukünftige Beiträge werden definitiv tiefer in das Objektmodell eintauchen, aber diese Information ist essentiell beim Lernen von Git. Die Bilder dieses Beitrags sind aus meiner Präsentation zu "Open Source Collaboration with Git and GitHub.":http://litanyagainstfear.com/blog/2008/12/05/open-source-collaboration-with-git-and-github/ + +Der einfachste Datenspeicher ist das Binärobjekt (Binary large object). Git speichert *einfach* die Inhalte einer Datei für die Verfolgungshistorie und nicht nur die Unterschiede zwischen den einzelnen Dateien jeder Änderung. Die Inhalte werden mit einem 40 Zeichen "SHA1 hash":http://de.wikipedia.org/wiki/Secure_Hash_Algorithm des Inhaltes versehen, so dass deren Eindeutigkeit gewährleistet ist. So ziemlich jedes Objekt, sei es eine Übergabe (Commit), Baum oder ein Binärobjekt hat einen SHA, lerne also sie zu lieben. Glücklicherweise sind sie durch eine einfache Zeichenfolge aus sieben Zeichen referenziert, die in der Regel ausreichen die gesamte Zeichenkette zu identifizieren. + +Ein grandioser Vorteil im Speichern der Inhalte besteht darin, dass Git bei zwei oder mehr Kopien der selben Datei intern nur eine Kopie vorhält. Ein Binärobjekt kann folgendermaßen dargestellt werden. + +p=. !/images/object1.png! + +Das nächste Objekt ist ein Baum. Man kann ihn sich als Ordner oder Verzeichniss vorstellen: Bäume beinhalten andere Binärobjekte oder Bäume. + +p=. !/images/object2.png! + +Das bringt uns schließlich zum wichtigsten Objekt: Die Übergabe (Commit). Man kann sich Übergaben (Commits) als Schnappschüsse vorstellen: Sie wissen wie der Baum zu einem bestimmten Zeitpunkt aussah. Darüber hinaus halten sie weitere Informationen wie Autor, Datum und Nachricht vor. + +p=. !/images/object3.png! + +Übergaben (Commits) werden in "gerichteten azyklischen Graphen":http://de.wikipedia.org/wiki/Gerichteter_azyklischer_Graph organisiert. Für jene, die diese Vorlesung in Datenstrukturen verpaßt haben, es bedeuted, dass Übergaben (Commits) in eine Richtung "fließen". Gewöhnlich ist diese Richtung einfach der Weg der Geschichte in deinem Repository, die recht einfach oder recht kompliziert sein kann, wenn du viele Zweige hast. Von einem umfassenden Standpunkt aus betrachtet, kann es wie folgt aussehen: + +p=. !/images/object4.png! + +Das alles wird mit dem Werkzeug "GitX":http://gitready.com/intermediate/2009/01/13/visualizing-your-repo.html offensichtlich. Ganz klar können hier die Übergabe-Objekte und ihre assoziierten Daten betrachtet werden. + +p=. !/images/object5.png! + +Wenn du nun einige komische Terminologien in deinen Übergaben (Commits) findest, wirst ein wenig besser verstehen, wo sie herkommen und wie es funktioniert. Schau einfach mal in der interessanten Anleitung "Git for Computer Scientists":http://eagain.net/articles/git-for-computer-scientists/ und in "Scott Chacon's":http://jointheconversation.org Referat zu "Getting Git":http://gitcasts.com/git-talk rein. diff --git a/_posts/2009-02-18-temporarily-ignoring-files.textile b/_posts/2009-02-18-temporarily-ignoring-files.textile new file mode 100644 index 0000000..4045640 --- /dev/null +++ b/_posts/2009-02-18-temporarily-ignoring-files.textile @@ -0,0 +1,69 @@ +--- +layout: post +title: Dateien temporär ignorieren +category: intermediate +--- + +Normalerweise ist das "Ignorieren von Dateien":http://gitready.com/beginner/2009/01/19/ignoring-files.html mit Git ziemlich einfach. Manchmal möchte man jedoch schnell eine Datei für die gesamte Entwicklungsphase oder aus anderen Gründen verstecken. Glücklicherweise gibt es hierfür einen einfachen Weg, dank einer cleveren Anleitung von "Eelco Wiersma":http://www.pagebakers.nl/2009/01/29/git-ignoring-changes-in-tracked-files/. + +Sein Hauptproblem war @git commit -a@, das automatisch veränderte Dateien zum Übergabe-Objekt (Commit) hinzufügt. Das ist eine nützliche Abkürzung, vergewissere dich aber, dass du die "Staging area verstehst":http://gitready.com/beginner/2009/01/18/the-staging-area.html, vor allem falls du feststellst, dass du dieses Kommando die ganze Zeit benutzt. + +Um temporär Änderungen in einer Datei zu ignorieren, ist folgender Befehl auszuführen: + +@git update-index --assume-unchanged @ + +Sollen die Änderungen wieder verfolgt werden: + +@git update-index --no-assume-unchanged @ + +Es kommen offensichtlich ein paar Einsprüche ins Spiel. Mit @git add@ wird die Datei direkt zum Index hinzugefügt. Das Zusammenführen (Merge) einer Übergabe (Commit) mit diesem aktivierten Schalter führt zum sanften Abbruch des Merges, so dass er manuell behandelt werden kann. + +Wir gehen durch ein kurzes Beispiel für dieses Kommando. An einigen Dateien im Arbeitsverzeichnis wurden Änderungen vorgenommen: + +
+$ git status
+# On branch master
+#
+# Changed but not updated:
+#   (use "git add ..." to update what will be committed)
+#
+#	modified:   README.textile
+#	modified:   Rakefile
+#	modified:   TODO
+#
+no changes added to commit (use "git add" and/or "git commit -a")
+
+ +Wenn ich @git commit -a@ an dieser Stelle ausführe, würden alle Dateien zur neuen Übergabe (Commit) hinzugefügt. Ich möchte jedoch die Änderungen in einer Datei temporär ignorieren: + +
+$ git update-index --assume-unchanged README.textile
+$ git status
+# On branch master
+#
+# Changed but not updated:
+#   (use "git add ..." to update what will be committed)
+#
+#	modified:   Rakefile
+#	modified:   TODO
+#
+no changes added to commit (use "git add" and/or "git commit -a")
+
+ +Wenn wir die Arbeit also jetzt committen und dann den Schalter deaktivieren, können wir sehen, dass Git die ursprünglichen Änderungen an README behalten hat. Von da an könntest du die Änderungen zu einer neuen Übergabe (Commit) hinzufügen oder "auf die aktuelle Kopie zurückgreifen":http://gitready.com/beginner/2009/01/11/reverting-files.html. + +
+$ git update-index --no-assume-unchanged README.textile
+$ git status
+# On branch master
+# Your branch is ahead of 'origin/master' by 4 commits.
+#
+# Changed but not updated:
+#   (use "git add ..." to update what will be committed)
+#
+#	modified:   README.textile
+#
+no changes added to commit (use "git add" and/or "git commit -a")
+
+ +Sieh "hier":http://www.kernel.org/pub/software/scm/git/docs/git-update-index.html in der Man Page für @git update-index@ nach. Falls du einen weiteren cleveren Trick zum Index kennst, hinterlasse einen Kommentar oder "Sende einen Tip!":/submit.html diff --git a/_posts/2009-02-19-what-git-is-not.textile b/_posts/2009-02-19-what-git-is-not.textile new file mode 100644 index 0000000..ca1b9c0 --- /dev/null +++ b/_posts/2009-02-19-what-git-is-not.textile @@ -0,0 +1,39 @@ +--- +layout: post +title: Was Git nicht ist +category: beginner +published: true +--- + +Es gibt offensichtliche viele Gründe, warum Git großartig ist (und warum es manchmal auch beschissen ist). Und es kommt der Zeitpunkt, wo es hilft einige Unruhen rund um Git auszuräumen. Die folgende Liste versucht aufzuzeigen, was Git *nicht ist*. Falls du deine eigenen Gründe hast, hinterlasse einen Kommentar und er möge hinzugefügt werden. + +h3. 1. Git ist nicht Subversion mit etwas eingestreutem Zucker. + +Git arbeitet sehr viel anders als SVN und CVS. Der wahrscheinlich größte Unterschied besteht darin, dass Git primär Inhalt speichert. Es arbeitet hauptsächlich mit Schnappschüssen (Snapshots) der verfügbaren Informationen. (Aus diesem Grund wird Git gewöhnlich als 'dummer Information Tracker' bezeichnet). Sein Algorithmus zum Speichern von Änderungen unterscheidet sich fundamental von Subversion. Git ist auf diese Weise sehr viel effizienter. + +Des Weiteren, solltest du es gewohnt sein alle deine Projekte in einem großen Repository zu haben, Git arbeitet auch so nicht. Repositories sind für einzelne Projekte gemeint und dann kannst "Submodule":http://book.git-scm.com/5_submodules.html benutzen, die andere Repositories einbinden, falls nötig. Ein Tip, der diese Situation behandelt, wird auf jeden Fall bald kommen. + +Die Unterschiede zwischen Git und SVN könnten in einer eigenen Serie von Tips behandelt werden, aber der "Git-SVN Crash +Course":http://git.or.cz/course/svn.html leistet großartige Arbeit für alle Jene, die den Umstieg durch die Betrachtung von Parallelen in Erwägung ziehen. + +h3. 2. Git ist nicht aufwändig bei Netzwerk oder Platzverbrauch + +Lokale Commits sind ein riesiger Vorteil bei der Verwendung von Git und es kann deinen Arbeitsablauf sehr viel angenehmer gestalten, weil Git für die meisten Aktionen nicht über das Netzwerk mit einem zentralen Server sprechen muss. Wenn du mehr darüber wissen möchtest, wie das funktioninert, lies den "Beitrag zur Staging Area":http://de.gitready.com/beginner/2009/01/18/the-staging-area.html oder diesen zu "Push und Pull":http://de.gitready.com/beginner/2009/01/21/pushing-and-pulling.html Ein weitere großartiger Vorteil ist *ein* Ort, wo Git seine Dateien für dein Repository speichert (gewöhnlich das @.git@ Verzeichnis) und es müllt dein Verzeichnis nicht mit tausenden von versteckten Verzeichnissen und Dateien zu, wie es SVN macht. + +h3. 3. Git ist nicht nur für Linux Kernel Hacker oder jene, die die ganze Zeit in Flugzeugen zu Konferenzen fliegen. + +Git kann so ziemlich auf jedem modernen Betriebssystem "installiert":http://gitready.com/beginner/2009/01/27/installing-git.html werden und es funktioniert definitiv auf Windows. Es gibt zwar keine 100%-ige graphische Unterstützung auf Windows, aber es wird eine Menge Integrationsarbeit für den Explorer und zahlreiche verfügbare Entwicklungsumgebungen geleistet. Es gibt eine Reihe von verfügbaren und gekonnten Werkzeugen auf anderen Betriebssystemen, wie zum Beispiel "GitX":http://gitx.frim.nl/ auf OSX. + +h3. 4. Git ist nicht schwer aufzusetzen + +Das Aufsetzen eines Git Repository ist so einfach wie das Ausführen von @git init@ in irgend einem Verzeichnis. Das kann fast kaum einfacher gehen. Beim Verteilen deiner Änderungen für andere Entwickler werden die Dinge ein bißchen interessanter. Gewöhnlich ist das "Verteilen von Änderungen":http://de.gitready.com/intermediate/2009/01/24/sharing-your-changes.html nur ein oder zwei Befehle entfernt. Die korrekte Bereitstellung deiner Änderungen kann jedoch ein wenig trickreich sein: Gewöhnlich ist für das eigene Setup die Verwendung von "gitosis":http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way zu empfehlen. Gitosis ist ein Werkzeug, das bei den SSH Benutzerschlüsseln für +den Commit-Zugriff hilft. + +h3. 5. Git ist nicht schwer zu lernen. + +Gits "Manpages":http://www.kernel.org/pub/software/scm/git/docs/user-manual.html sind recht umfangreich (und ausufernd). Online sind noch weitere Anleitungen zum Lernen verfügbar. Einige der besten sind im Bereich Quellen in der Fußzeile dieser Seite gelistet! Den Git-Neulingen empfehle ich gewöhnlich das "Git Community Book":http://book.git-scm.com/ und das Ansehen der "Gitcasts":http://gitcasts.com. (Das Lesen dieser Website zählt auch!) + +h3. 6. Git ist nicht komplex. + +Ja, es gibt eine Menge ungewohnter Terminologien und einige Konzepte sind nicht jedem Neuling sofort vertraut. Aber die darunterliegenden Konzepte, auf denen das System aufbaut, sind fundamental und absichtlich einfach gehalten. Ein großartiges Beispiel ist die "blob-tree-commit Struktur":http://de.gitready.com/beginner/2009/02/17/how-git-stores-your-data.html. Sobald die Grundkonzepte hinter Git verstanden sind, ist es wirklich sehr einfach, das Werkzeug auf deine Weise arbeiten zu lassen, anstatt in einen bestimmten Ablauf gezwungen zu werden. Sicher, zu viel Flexibilität könnte schlecht sein, aber wenn Git so viel Macht und Einfachheit in der Benutzung anbietet, warum sollte es dann ungenutzt +bleiben? diff --git a/_posts/2009-02-23-finding-who-committed-what.textile b/_posts/2009-02-23-finding-who-committed-what.textile new file mode 100644 index 0000000..3702e21 --- /dev/null +++ b/_posts/2009-02-23-finding-who-committed-what.textile @@ -0,0 +1,24 @@ +--- +layout: post +title: Herausfinden, wer was übergeben (committet) hat +category: beginner +--- + +Manchmal könnte es nötig sein herauszufinden, wer einen Fehler übergeben (committed) hat. Oder du möchtest einen Kollegen für die effiziente Implementierung eines Algorithmus beglückwünschen. Oder vielleicht auch nicht und du möchtest einfach nur herausfinden, wer den Build vermurkst hat. Glücklicherweise gibt es den @git blame@ Befehl, der genau dabei hilft und herausfindet, wer für welche Zeile verantwortlich ist und aus welcher Übergabe (Commit) sie kam. + +Die einfach Verwendung ist ein schlichtes @git blame @. Die Konsolenausgabe sieht gewöhnlich ähnlich wie folgt aus: + +p=. "!http://farm4.static.flickr.com/3606/3304779985_6c93865703.jpg!":http://farm4.static.flickr.com/3606/3304779985_2d1842b5f9_o.png + +Die Textwand mag einige von euch verwirren. Sie zeigt den verkürzten SHA der Übergabe (Commits), den Dateinamen, den Autor, das Datum, die Zeilennummer und die tatsächliche Quellcodezeile. + +Das allein ist natürlich schon großartig, aber es gibt eine Reihe von anderen Wegen den Verantwortlichen zu finden. Wenn dein Quellcode auf GitHub liegt, sind diese Informationen bereits eingebaut. + +p=. "!http://farm4.static.flickr.com/3463/3305616220_05a91c8e70.jpg!":http://farm4.static.flickr.com/3463/3305616220_a7b2850e62_o.jpg + +Ein anderer schöner Weg diese Informationen zu sehen, ist mit "git-age":http://wiki.github.com/krig/git-age. Es ist ein in PyGtk geschriebener Betrachter. Er ist recht nett und zeigt den Gravater zusammen mit der E-Mail der Übergabe (Commits), ältere Übergaben (Commits) werden mit einem dunkleren grauen Hintergrund dargestellt. + +p=. "!http://farm4.static.flickr.com/3454/3305608128_7000ca6fa2.jpg!":http://farm4.static.flickr.com/3454/3305608128_94edf84e1b_o.png + +Solltest du einen weiteren Trick zu diesem Befehl oder weiteren nützlichen Betrachtern kennen, teile ihn uns als Kommentar mit! + diff --git a/_posts/2009-02-25-keep-either-file-in-merge-conflicts.textile b/_posts/2009-02-25-keep-either-file-in-merge-conflicts.textile new file mode 100644 index 0000000..7d68dbf --- /dev/null +++ b/_posts/2009-02-25-keep-either-file-in-merge-conflicts.textile @@ -0,0 +1,44 @@ +--- +layout: post +title: Eine von beiden Dateien in einem Merge-Konflikt behalten +category: advanced +published: true +--- + +Beim Auflösen eines Merge-Konflikts, möchte man manchmal einfach die eine oder die andere Datei behalten. Du musst nicht die einzelnen Dateien öffnen und hunderte von Konflikten beheben. Du brauchst nur die gewünschte Datei auswählen und schon bist du fertig. Bedauerlicherweise ist das in älteren Version von Git nicht besonders klar, aber in jüngeren Versionen ist es viel einfacher. Großen Dank an "Kevin Old":http://kevinold.com für "seinen Beitrag zu dem Thema":http://www.kevinold.com/2009/02/24/better-git-conflict-resolution-between-binaries-with-theirs.html, der mich an das Problem erinnerte. + +Hier das Szenario: Du bist mittendrin in einem Merge und du möchtest die eine oder die andere Datei behalten. + +
+$ git merge master     
+  Auto-merged _layouts/default.html
+  CONFLICT (content): Merge conflict in _layouts/default.html
+  Auto-merged index.html
+  CONFLICT (content): Merge conflict in index.html
+  Automatic merge failed; fix conflicts and then commit the result.
+
+ +Hier gibt es zwei Dateien, die nicht verschmolzen (merged) sind. Laut "git checkout":http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html Manpage gibt es eine @--theirs@ und @--ours@ Option für den Befehl. Die erste Option behält die Version der Datei, die du einbringst und die andere Option behält die Datei in ihrer Originalfassung. + +Die folgenden Befehle behalten unsere Version für index.html und verwenden dann nur die andere Version der Datei _layouts/default.html. + +
+git checkout --ours index.html
+git checkout --theirs _layouts/default.html
+
+ +Bedauerlicherweise gibt es diese Optionen nur in Git 1.6.1 und höher. Wenn du eine ältere Version verwendest und nicht aktualisieren möchtest, gibt es eine Umleitung. Um @--theirs@ zu emulieren, ist folgendes zu tun: + +
+git reset -- _layouts/default.html
+git checkout MERGE_HEAD -- _layouts/default.html
+
+ +Und für @--ours@: + +
+git reset -- index.html
+git checkout ORIG_HEAD -- index.html
+
+ +Sobald die Konflikte gelöst sind, übernimmt @git add@ die notwendigen Änderungen und @git commit@ bestätigt sie. Wenn du beim Merge Probleme hattest, deren Lösung anderen helfen könnte, einfach einen Kommentar abgeben. diff --git a/_posts/2009-02-27-get-a-file-from-a-specific-revision.textile b/_posts/2009-02-27-get-a-file-from-a-specific-revision.textile new file mode 100644 index 0000000..e3fcb31 --- /dev/null +++ b/_posts/2009-02-27-get-a-file-from-a-specific-revision.textile @@ -0,0 +1,20 @@ +--- +layout: post +title: Eine Datei aus eine bestimmten Revision laden +category: intermediate +published: true +--- + +Wenn du weißt, wie Git Daten durch "Blobs, Bäume und Commits":http://de.gitready.com/beginner/2009/02/17/how-git-stores-your-data.html speichert, macht es hoffentlich Sinn, warum es ein wenig ärgerlich ist, eine bestimmte Revision einer Datei aus deinem Repository zu holen. Was du haben möchtest, befindet sich in einem Blob in irgendeinem Commit. Einfach den Commit anzusehen, wird es also nicht bringen. Du könntest dein Arbeitsverzeichnis zu dem gewünschten Commit zurück setzen und dann in den Datei schauen, aber das ist lahm. + +Wir schauen uns @git show@ an, ein großartiges Werkzeug für diese Aufgabe. Dieser Befehl ist ziemlich vielseitig und verdient verschiedene Tips zu seinem Können. Wir konzentrieren uns aber zunächst auf die greifbare Aufgabe: Wir möchten den Inhalt einer Datei aus einer bestimmten Revision ziehen. Gewöhnlich würde der Befehl ungefähr so aussehen: + +@git show :@ + +Nehmen wir also an, wir möchten vier Commits von unserem aktuellen HEAD zurück gehen und wir möchten die Datei index.html ansehen. + +@git show HEAD~4:index.html@ + +Natürlich könntest du jeden gültigen "treeish":http://book.git-scm.com/4_git_treeishes.html an den Befehl übergeben. Er wird auch den tatsächlichen SHA1 des Blobs akzeptieren, aber das ist ziemlich unwahrscheinlich für die meisten Anwendungsfälle. Die wahrscheinlich beste Verwendung des Befehls ist zu sehen, wie die Datei aussah, und vielleicht wird ihr Inhalt in eine neue Datei geschrieben (oder die alte Datei ersetzt!), wenn das gewünscht ist. + +Weitere Verwendungsmöglichkeiten dieses Befehls findest du in der "Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-show.html. Und falls du andere nützliche Tips hast, teile sie uns mit und "sende uns einen Tip!":/submit.html diff --git a/_posts/2009-03-02-where-to-find-the-git-community.textile b/_posts/2009-03-02-where-to-find-the-git-community.textile new file mode 100644 index 0000000..f337f90 --- /dev/null +++ b/_posts/2009-03-02-where-to-find-the-git-community.textile @@ -0,0 +1,31 @@ +--- +layout: post +title: Wo die Git Community zu finden ist +category: beginner +--- + +Für jene, die sich mit Git beschäftigen, könnte das Wissen, wo die Git Community täglich herumhängt, hilfreich sein. Natürlich sind online eine +Menge Quelle für jene verfügbar, die lernen möchten, wie man Git benutzt. Aber manchmal ist die Kommunikation und Teilnahme an Diskussionen sehr viel vorteilhafter und wünschenswert. + +Dieser Beitrag nennt ein paar Orte, wo du genau die Leute finden kannst, die eine Leidenschaft für Git haben und hoffentlich auch deine Fragen +beantworten. Solltest du einen Ort kennen, der hier vergessen wurde, lass es uns in einem Kommentar wissen! + +1) Der #git channel auf "FreeNode":http://freenode.net/. + +Für die Freunde der Echtzeitkommunikation ist IRC der beste Weg. Bitte beachte aber: Die Teilnehmer im Channel sind Freiwillige! Informationen +einfordern oder einfach nur um Hilfe trollen, bringt dich nicht sehr weit. Hänge einfach im Channel herum und beobachte die vorbei fliegenden +Gespräche. Du könntest dabei etwas lernen! + +2) "Github":http://github.com + +Diese Seite ist der heißeste Platz, um Open Source Projekte zusammen mit deinem eigenen privaten Code unterzubringen. Der Vorteil besteht darin, +dass du eine Menge anderer Benutzer finden kannst, die Git täglich benutzen und wie sie es nutzen. Es gibt eine Menge verschiedener +Modelle, die du beobachten kannst: Alles vom einzelnen Entwickler, der an Hobby-Projekten arbeitet, bis hin zu sehr aktiven +Entwicklungsprojekten mit Zehn bis Hunderten von Forks (Abspaltungen). Solltest du noch kein Konto haben, melde dich an und finde ein Projekte +deiner "Lieblingssprache":http://github.com/languages. + +3) Die "Git Mailing List":http://vger.kernel.org/vger-lists.html#git + +Die offizielle Mailingliste der Git Entwickler ist überaus aktiv und wohl der beste Weg mit jenen in Kontakt zu treten, die Git nicht nur +täglich benutzen, sondern eine maßgebliche Rolle in seiner Entwicklung spielten. Deine Frage wird höchstwahrscheinlich dort beantwortet. Stelle +aber sicher, dass du deine "Hausaufgaben":http://letmegooglethatforyou.com machst, bevor du fragst! Hier fängst du auch an, wenn du selbst zu Git beitragen möchtest. diff --git a/_posts/2009-03-04-pick-out-individual-commits.textile b/_posts/2009-03-04-pick-out-individual-commits.textile new file mode 100644 index 0000000..3d9db8f --- /dev/null +++ b/_posts/2009-03-04-pick-out-individual-commits.textile @@ -0,0 +1,114 @@ +--- +layout: post +title: Einzelne Commits auswählen +category: intermediate +published: true +--- + +Du möchtest manchmal vielleicht nur einen Commit aus einem Branch oder nur eine Datei aus einem Changeset lesen. Dieser Beitrag beschäftigt sich mit der Frage, wie man einzelne Commits auswählt und mit ihnen arbeitet. + +p=. "!http://farm4.static.flickr.com/3290/2767960923_92b8e5a8db.jpg!":http://flickr.com/photos/waltjabsco/2767960923/ + +Beim einfachen Fall siehst du einen anderen Branch oder vielleicht den Fork eines Projekts, aber du möchtest nur einen Commit, ein paar wenige Commits oder was auch immer du hast, übernehmen. Glücklicherweise hat Git eine ganze Menge an Werkzeugen, um dir diese Aufgabe zu erleichtern. Hier ist as Szenario. Es gab in letzter Zeit eine ganze Menge an Entwicklungen an "jekyll":http://github.com/mojombo/jekyll, aber ich möchte nur oder zwei einzelne Changesets übernehmen. Das Repository sieht folgendermaßen aus: + +p=. !/images/pick.png! + +Wie du sehen kannst, ist unser Hauptzweig (master) um unteren Ende dieser aufregenden Entwicklung und darüber gibt es eine ganze Reihe an Aktivitäten. Ich möchte jedoch nur den markierten Commit in mein Repository übernehmen. Sobald der SHA bekannt ist, gibt es ein paar Optionen: + +1) Benutze @git cherry-pick@ zur Auswahl des Commits. Das erzeugt einen neuen Commit und behält die Metadaten der alten Übergabe bei. + +2) Erzeuge einen Patch mit @git format-patch@ und übernehme ihn mit @git am@. Das erlaubt dir eine Gegenzeichnung des Commits mit @--signoff@. Auch dieser Schritt erzeugt einen neuen Commit. + +3) Benutze @git apply@ mit dem Patch, um die Änderungen in dein Arbeitsverzeichnis zu übernehmen und sie weiter zu bearbeiten. + +4) Übernehme die Änderungen direkt mit @git merge@. Dieser Weg bewahrt den ursprünglichen Commit, sofern keine Konflikte auftreten. + +Wir versuchen alle vier Möglichkeiten. Wir kennen den SHA b50788b des Commits und können mit ihm arbeiten. Als erstes wählen wir den Commit mit "cherry-pick":http://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html. + +
+$ git cherry-pick b50788b
+Finished one cherry-pick.
+[master]: created bcb0d1b: "First pass at rake task."
+ 3 files changed, 63 insertions(+), 3 deletions(-)
+ create mode 100644 lib/jekyll/task.rb
+
+$ git log --pretty=oneline --abbrev-commit HEAD~3..HEAD
+bcb0d1b... First pass at rake task.
+2569e9f... update history
+2135a53... Using block syntax of popen4 to ensure that subprocesses...
+
+ +Wie du sehen kannst, wurde ein neuer Commit erzeugt und die Arbeit wurde erfolgreich übernommen. Die erste und dritte Methode erzeugen beide eine ähnliche Historie mit einem neuen Commit: + +p=. !/images/pick-cherry.png! + +Mit "format-patch":http://www.kernel.org/pub/software/scm/git/docs/git-format-patch.html wird ein Commit eingepackt und mit "git am"::http://www.kernel.org/pub/software/scm/git/docs/git-am.html angewendet. + +
+$ git format-patch -1 b50788b
+0001-First-pass-at-rake-task.patch
+
+$ git am 0001-First-pass-at-rake-task.patch
+Applying: First pass at rake task.
+
+$ git log --pretty=oneline --abbrev-commit HEAD~3..HEAD
+c05eaa1... First pass at rake task.
+2569e9f... update history
+2135a53... Using block syntax of popen4 to ensure that subprocesses...
+
+ +Über diesen Prozess werden normalerweise Patches per E-Mail angenommen. Aber die Methode funktioniert ebenso für unsere Zwecke. Natürlich könnten @format-patch@ und @am@ über eine Pipe zu einem Befehl zusammengefügt werden. Auf diese Weise musst du dich nicht um die zusätzliche Datei kümmern, die sonst erzeugt werden würde. + +Als nächstes benutzen wir "git apply":http://www.kernel.org/pub/software/scm/git/docs/git-apply.html und erhalten die Änderungen in unserem Arbeitsverzeichnis und können noch an ihnen arbeiten. + +
+$ git format-patch -1 b50788b
+0001-First-pass-at-rake-task.patch
+
+$ git apply 0001-First-pass-at-rake-task.patch 
+0001-First-pass-at-rake-task.patch:59: trailing whitespace.
+
+0001-First-pass-at-rake-task.patch:75: trailing whitespace.
+    private
+warning: 2 lines add whitespace errors.
+
+$ git status
+# On branch master
+# Changed but not updated:
+#   (use "git add ..." to update what will be committed)
+#   (use "git checkout -- ..." to discard changes in working directory)
+#
+# modified:   jekyll.gemspec
+# modified:   lib/jekyll.rb
+#
+# Untracked files:
+#   (use "git add ..." to include in what will be committed)
+#
+# 0001-First-pass-at-rake-task.patch
+# lib/jekyll/task.rb
+no changes added to commit (use "git add" and/or "git commit -a")
+
+ +Abschließend können wir den Commit mit einem Merge übernehmen, was in diesem Fall sehr einfach ist, da keine Konflikte auftreten. + +
+$ git merge b50788b
+Updating 2569e9f..b50788b
+Fast forward
+ jekyll.gemspec     |    6 ++--
+ lib/jekyll.rb      |    2 +
+ lib/jekyll/task.rb |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 63 insertions(+), 3 deletions(-)
+ create mode 100644 lib/jekyll/task.rb
+
+$ git log --pretty=oneline --graph --abbrev-commit
+b50788b... First pass at rake task.
+2569e9f... update history
+2135a53... Using block syntax of popen4 to ensure that subprocesses...
+
+ +Die Grafik zeigt die Übernahme des Commits auf der linke Seite in die Hauptlinie: + +p=. !/images/pick-merge.png! + +Du kannst, wie immer, mit @git reset --hard HEAD^@ einen Commit zurück gehen, falls etwas nach der Anwendung des Patches schief gelaufen ist. Vielleicht ist es sogar möglich, ein "Revert der Dateien":http://de.gitready.com/beginner/2009/01/11/reverting-files.html durchzuführen. Wenn alles drunter und drüber geht, kannst du immer noch das "Reflog prüfen":http://de.gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html. Wenn du andere Wege kennst, wie man mit dieser Situation klar kommt, teile sie uns mit einem Kommentar mit! diff --git a/_posts/2009-03-06-ignoring-doesnt-remove-a-file.textile b/_posts/2009-03-06-ignoring-doesnt-remove-a-file.textile new file mode 100644 index 0000000..de08091 --- /dev/null +++ b/_posts/2009-03-06-ignoring-doesnt-remove-a-file.textile @@ -0,0 +1,20 @@ +--- +layout: post +title: Ignorieren entfernt keine Datei +category: beginner +published: true +--- + +Im #git Channel auf Freenode sehe ich häufig verwirrte Anfänger mit der Frage, warum eine Datei nicht aus ihrer Historie verschwindet, wenn sie sie in ihre ".gitignore":http://de.gitready.com/beginner/2009/01/19/ignoring-files.html Datei einfügen. Die Antwort darauf ist ziemlich einfach! Wenn Git eine Datei ignoriert, werden *nur* Änderungen an dieser Datei nicht mehr beobachtet und nichts weiter. Das bedeutet, dass die Historie die Datei beibehalten wird, sofern sich die Datei bereits im Repository befindet. + +Wenn du eine Datei aus dem Repository löschen, aber im Arbeitsverzeichnis behalten möchtest, verwende einfach: + +@git rm --cached @ + +Dieser Befehl behält die Datei aber immer noch in der Historie. Wenn du die Datei tatsächlich aus der History löschen möchtest, hast du zwei Optionen: Deine Repository-Commits neu schreiben oder komplett von vorne beginnen. Beide Optionen sind wirklich Mist und das aus gutem Grund: Git versucht wirklich hart, keine Daten zu verlieren. Wie beim "Rebasing":http://de.gitready.com/intermediate/2009/01/31/intro-to-rebase.html zwingt dich Git dazu, über diese Optionen nachzudenken, weil es zerstörerische Operationen sind. + +Wenn du tatsächlich eine Datei aus deiner Historie löschen möchtest, ist @git filter-branch@ die Bügelsäge, nach der du suchst. Schau vor der Verwendung des Befehls besser noch in die "Manpage":http://www.kernel.org/pub/software/scm/git/docs/git-filter-branch.html, weil er buchstäblich die Commits deine Projekts neu schreibt. Für einige Aktionen ist der Befehl ein großartiges Werkzeug, das eine ganze Reihe Zeugs beherrscht wie beispielsweise vom kompletten Löschen eines Commit eines Autors bis hin zum Umbewegen des Hauptverzeichnisses des Projektes. Der Befehl zum Löschen einer Datei aus allen Revisionen lautet: + +@git filter-branch --index-filter 'git rm --cached ' HEAD@ + +Diese Aktion kann durchaus sehr nützlich sein, wenn du empfindliche oder vertrauliche Informationen ausschwärzen möchtest, die in deinem Repository zu finden sind. Weitere zukünftige Tips werden andere nützliche Dinge von @filter-branch@ behandeln. Wenn du andere nützliche Tips kennst, teile sie uns in den Kommentaren mit oder "übermittle einen Tip!":/submit.html diff --git a/_posts/2009-03-09-remote-tracking-branches.textile b/_posts/2009-03-09-remote-tracking-branches.textile new file mode 100644 index 0000000..bab9a1e --- /dev/null +++ b/_posts/2009-03-09-remote-tracking-branches.textile @@ -0,0 +1,65 @@ +--- +layout: post +title: Remote-tracking Branches +category: beginner +published: true +--- + +Verwirrt darüber, was genau remote-tracking Branches sind? Keine Sorge, es "geht nicht nur dir so":http://kerneltrap.org/mailarchive/git/2007/8/4/253944. Es gibt grundsätzlich zwei Arten von Branches: lokal und remote-tracking. Lokale Branches sind alltäglich. Sie sind einfach ein anderer Pfad im "DAG":http://de.gitready.com/beginner/2009/02/17/how-git-stores-your-data.html, in den man einchecken kann. Remote-tracking Branches haben ein paar andere Absichten: + +# Sie werden dazu verwendet, um die lokale Arbeit mit der Arbeit in einem entfernten Repository zu verbinden. +# Sie wissen automatisch, von welchem entfernten Branch Änderungen heruntergeladen werden müssen, wenn @git pull@ oder @git fetch@ verwendet werden. +# Und noch besser, @git status@ erkennt, wieviele Commits die aktuelle Arbeit der entfernten Version des Branches voraus ist. + +Glücklicherweise gibt der @git branch@ Befehl Einblick darin, welcher Branch was ist. Bei frisch geklonten Repositories ist für gewöhnlich folgende Ausgabe zu sehen: + +
+$ git branch
+* master
+
+ +Das zeigt nur den üblichen lokalen Branch, den Master. Für die entfernten Branches ist folgender Befehl nötig: + +
+$ git branch -r
+  origin/HEAD
+  origin/master
+
+ +Und wenn schließlich alle Branches angezeigt werden sollen: + +
+$ git branch -a
+* master
+  origin/HEAD
+  origin/master
+
+ +Sobald Branches mit der @--track@ Option erstellt werden, sind sie als Verbindung zum Remote Branch konfiguriert. Möchte man zum Beispiel einen neuen Branch vom Master Branch aus dem origin Repository erzeugen, würde das in diesem Fall einen Branch ergeben, der automatisch mit dem entfernen Branch verbunden ist und von dem so direkt die Commits geladen werden können: + +
+$ git branch --track feature1 origin/master
+Branch feature1 set up to track remote branch refs/remotes/origin/master.
+
+ +Von hier aus kann man den Branch mit @git checkout@ auswählen und damit arbeiten. Und weil der entfernte Branch verfolgt wird, weiß Git, wo die Änderungen bei einem Fetch oder Pull eingebracht werden müssen. + +Lokale Branches können auch von jedem beliebigen Startpunkt erzeugt werden, sei es ein remote-tracking Branch oder jede andere übergebene "treeish":http://book.git-scm.com/4_git_treeishes.html Option. Hier sind ein paar Beispiele: + +
+$ git branch --no-track feature2 origin/master 
+$ git branch --no-track feature3 HEAD~4
+$ git branch --no-track feature4 f21e886
+
+ +In diesen Beispielen wurde die Option @--no-track@ übergeben. Damit wird sichergestellt, dass die Branches nicht von einem remote-tracking Branch abgeleitet werden. Man kann diese Verhaltensweise in der Datei @~/.gitconfig@ einstellen. Wie das "Git Cheat Sheet":http://cheat.errtheblog.com/s/git/ hierzu sagt: + +
+git config branch.autosetupmerge true
+tells git-branch and git-checkout to setup new branches so that git-pull(1) +will appropriately merge from that remote branch. Recommended. Without this, +you will have to add --track to your branch command or manually merge remote +tracking branches with "fetch" and then "merge". +
+ +Dieser Beitrag löste hoffentlich die Verwirrung um Branches und was genau remote-tracking Branches machen ein wenig auf. Wenn du weitere Ideen für bessere Erklärungen oder vergleichbare Ressourcen hast, teile sie uns in den Kommentaren mit oder "schicke uns einen Tip!":http://gitready.com/submit.html diff --git a/_posts/2009-03-11-easily-manage-git-remote-branches.textile b/_posts/2009-03-11-easily-manage-git-remote-branches.textile new file mode 100644 index 0000000..68e99cd --- /dev/null +++ b/_posts/2009-03-11-easily-manage-git-remote-branches.textile @@ -0,0 +1,34 @@ +--- +layout: post +title: Entfernte Branches einfach verwalten +category: advanced +published: true +--- + +"Entfernte Branches auschecken":http://de.gitready.com/intermediate/2009/01/09/checkout-remote-tracked-branch.html, "sie löschen":http://de.gitready.com/beginner/2009/02/02/push-and-delete-branches.html und neue veröffentlichen ist Teil der gewöhnlichen Arbeitsweise der meisten Git-Anwender. Aber ernsthaft, wer möchte schon *so* viel tippen? Ich sicherlich nicht, und das solltest du auch nicht müssen. + +Schau dir nur für diese Aufgabe "git_remote_branch":http://grb.rubyforge.org/ näher an, ein nützlicher "RubyGem":http://rubygems.org. Es wird eine neue ausführbare Datei installiert, die bei einigen täglichen Aufgaben mit entfernten Branches hilft. Hier sind einige Befehle, die enthalten sind: + +
+grb create branch_name [origin_server]
+
+grb publish branch_name [origin_server]
+
+grb rename branch_name [origin_server]
+
+grb delete branch_name [origin_server]
+
+grb track branch_name [origin_server]
+
+ +Was ist daran so großartig? Beim Ausführen werden die darunter liegenden Git-Befehle angezeigt. So ist es ziemlich einfach, herauszufinden, was geschieht. + +p=. !/images/grb1.png! + +Es gibt sogar einen eingebauten @explain@ (Erklär-) Befehl, der die Befehle direkt ausgibt. + +p=. !/images/grb2.png! + +Vorausgesetzt "RubyGems ist installiert":http://rubyforge.org/frs/?group_id=126, kannst du einfach @gem install git_remote_branch@ ausführen und bist fertig. Schau in den Code auf "GitHub":http://github.com/webmat/git_remote_branch/tree, wenn du Ideen zur Verbesserung hast (oder du möchtest deine eigenen nützlichen Befehle auf dieser Grundlage schreiben!) + +Wenn du andere hilfreiche Abkürzungen kennst, die Git-Benutzern helfen können, "schicke uns einen Tip!":http://de.gitready.com/submit.html diff --git a/_posts/2009-03-13-smartly-save-stashes.textile b/_posts/2009-03-13-smartly-save-stashes.textile new file mode 100644 index 0000000..5b1e231 --- /dev/null +++ b/_posts/2009-03-13-smartly-save-stashes.textile @@ -0,0 +1,49 @@ +--- +layout: post +title: Zwischenschritte als Stashes clever speichern +category: beginner +published: true +--- + +Ich verwende zunehmend "Stashes":http://de.gitready.com/beginner/2009/01/10/stashing-your-changes.html und finde, dass die Ausgabe der Stash-Liste wie folgt meistens nicht sehr nützlich ist: + +
+$ git stash list
+stash@{0}: WIP on feature1: b50788b... First pass...
+stash@{1}: WIP on master: b50788b... First pass...
+stash@{2}: WIP on shoulda: e783fb0... Upgrading the rest...
+
+ +Nun, sie enthält den Commit-Hash und die Beschreibung, auf dem die Arbeit aufbaut. Aber wenn du nur ein kleines bißchen ähnlich tickst wie ich, dann hast du in dem Moment, wo du deinen Arbeitsfortschritt im Stash verstaust und diesen nervigen Bug über Stunden bearbeitest, vergessen, woran du gearbeitest hast. + +Stattdessen ist das zwischenzeitliche Verstauen der gegenwärtigen Arbeit auf die folgende Art sehr viel besser, wenn du dich wieder einarbeitest und tatsächlich herausfinden möchtest, wo du warst: + +@git stash save "your message here"@ + +Jetzt sehen die Stash-Listen ein ganzes Stück sauberer aus. Hoffentlich spart dir das etwas Zeit, anhand der Informationen wieder in die Arbeit hinein zu finden. + +
+$ git stash list
+stash@{0}: On shoulda: Updating instructions
+stash@{1}: On master: started merge but need to fix #104 first
+stash@{2}: On feature1: Adding some stuff
+
+ +Wenn du sehen möchtest, was in einem bestimmten Stash geändert wurde, kannst du einfach den Treeish der Stash-Ausgabe von @git stash list@ weitergeben. Der Teil stash@{} zeigt, wie der Änderungssatz referenziert wird. Einfach an @git diff@ übergeben und du siehst, was geändert wurde: + +
+$ git diff stash@{0}
+diff --git a/TODO b/TODO
+index b0ecaeb..4ca398c 100644
+--- a/TODO
++++ b/TODO
+@@ -1,4 +1,3 @@
+ [ ] Easier configuration of Maruka and blahtex directories [mdreid]
+ [ ] Accurate "related posts" calculator
+-[ ] Autobuild
+-[ ] Add more awesome.
++[ ] Autobuild
+\ No newline at end of file
+
+ +Du könntest auch @git show@ verwenden, um zu sehen, worauf der Commit basiert. Wenn du weitere Stash-bezogene oder andere Tips hast, "lass es uns wissen!":http://gitready.com/submit.html diff --git a/_posts/2009-03-16-rolling-back-changes-with-revert.textile b/_posts/2009-03-16-rolling-back-changes-with-revert.textile new file mode 100644 index 0000000..e177f60 --- /dev/null +++ b/_posts/2009-03-16-rolling-back-changes-with-revert.textile @@ -0,0 +1,73 @@ +--- +layout: post +title: Änderungen mit revert zurückrollen +category: intermediate +published: true +--- + +Du hast alles erledigt. Vielleicht hattest du am Vormittag nicht genügend Kaffee oder es war kurz vor dem Mittagessen, doch irgendwie kam der Bug in das Repository und du möchtest ihn wieder raus bekommen. Glücklicherweise ist @git revert@ das nötige Skalpell, um den kontaminierten Commit wieder heraus zu operieren. + +p=. "!http://farm2.static.flickr.com/1032/1449240840_a61f776d69_m.jpg!":http://www.flickr.com/photos/cheryl/1449240840/ + +Nehmen wir an, unsere Historie sieht wie folgt aus: + +p=. !/images/revert1.png! + +Der "revert"-Befehl arbeitet ungefährt so: Es werden alle Änderungen aus dem letzten Commit umgedreht und damit ein neuer Commit erzeugt. Um also den letzten Commit im aktuellen Branch zurückzurollen, reicht folgender Befehl: + +
+$ git revert HEAD
+Finished one revert.
+[master]: created 1e689e2: 
+  "Revert "Updated to Rails 2.3.2 and edge hoptoad_notifier""
+
+ +Unser Repository würde dann ungefähr so aussehen: + +p=. !/images/revert2.png! + +Du kannst auch jeglichen Hash für jeden Commit übergeben, um dessen Änderungen zurückzurollen. Falls der Commit zum Zurückrollen nicht sauber angewendet werden kann, muss der Merge natürlich manuell aufgelöst werden. + +Standardmäßig öffnet der Befehl deinen @EDITOR@, um die Commit-Nachricht des Reverts zum Zurückrollen der Änderungen zu bearbeiten. Nutze diese Gelegenheit, um das Zurückrollen der Änderungen kurz zu erläutern! Wenn du die Commit-Nachricht aus irgendwelchen Gründen nicht bearbeiten willst, wird das durch die Option @--no-edit@ ermöglicht. + +Eine andere nützliche Option ist das Argument @-n@ oder @--no-commit@. Sie belässt die zurückgerollten Änderungen einfach in deinem Arbeitsverzeichnis und wendet sie nicht automatisch an. Wenn Dateien für die Vollendung des Reverts weiter bearbeitet oder mehrere Commits zurückgerollt werden müssen, ist diese Option genau richtig. + +Das Zurückrollen von Merges ist etwas ärgerlich. Es kann sein, dass du folgende Nachricht beim Zurückrollen eines Merges bekommst: + +
+$ git revert HEAD~1
+fatal: Commit 137ea95 is a merge but no -m option was given.
+
+ +Bei Merges musst du einen der zusammengeführten Commits auswählen, zu denen zurückgerollt werden soll. Mit der Option @-m@ oder @--mainline@ kannst du jenen Commit auswählen, der Teil der 'Hauptlinie' ist. Die Option erfordert ein nummerisches Argument und das kann etwas irreführend sein. Schauen wir uns den Merge-Commit von oben an: + +
+$ git log HEAD~1 -1
+commit 137ea95c911633d3e908f6906e3adf6372cfb0ad
+Merge: 5f576a9... 62db4af...
+Author: Nick Quaranto 
+Date:   Mon Mar 16 16:22:37 2009 -0400
+
+    Merging in rails-2.3 branch
+
+ +Wenn wir ein @git revert HEAD~1 -m 1@ durchführen, wird der erste Commit des Merges zurückgerollt (@5f576a9@). Die Option @-m 2@ wird den zweiten Commit zurückrollen (@62db4af@). Es gilt herauszufinden, welcher Commit zurückgerollt werden soll. Die standardmäßige Commit-Nachricht zeigt den Commit, der zurückgerollt wurde. + +
+$ git revert HEAD~1 --no-edit --mainline 2
+Finished one revert.
+[master]: created 526b346: "Revert "Merging in rails-2.3 branch""
+
+$ git log -1
+commit d64d3983845dfa18a5d935c7ac5a4855c125e474
+Author: Nick Quaranto 
+Date:   Mon Mar 16 19:24:45 2009 -0400
+
+    Revert "Merging in rails-2.3 branch"
+
+    This reverts commit 137ea95c911633d3e908f6906e3adf6372cfb0ad, reversing
+    changes made to 62db4af8c77852d2cc9c19efc6dfb97e0d0067f5.
+
+ +Die Git-Dokumentation schlägt einen Blick in "diese Nachricht von Linus":http://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.txt vor, wenn du etwas Hilfe beim Auflösen von Merges benötigst. Ich werde hoffentlich bald ein paar bessere Beiträge für diese Situationen haben. Wenn du andere großartige Verwendungen für das Zurückrollen von Commits hast (oder vielleicht sogar Horrorgeschichten oder wie es dich gerettet hat) "lass es uns wissen":http://de.gitready.com/submit.html! + diff --git a/_posts/2009-03-18-restoring-a-directory-from-history.textile b/_posts/2009-03-18-restoring-a-directory-from-history.textile new file mode 100644 index 0000000..95a7431 --- /dev/null +++ b/_posts/2009-03-18-restoring-a-directory-from-history.textile @@ -0,0 +1,41 @@ +--- +layout: post +title: Ein Verzeichnis aus der Historie wiederherstellen +category: intermediate +published: true +--- + +Es ist ziemlich einfach eine einzelne Datei aus der Historie "zurückzurollen":http://de.gitready.com/intermediate/2009/03/16/rolling-back-changes-with-revert.html oder "wiederherzustellen":http://de.gitready.com/beginner/2009/01/11/reverting-files.html. Aber wie wird ein gesamtes Verzeichnis aus der Historie wiederhergestellt? + +p=. "!/images/stump.png!":http://www.flickr.com/photos/stevejaysbestshots/1402673467/ + +Die Lösung ist einfach: + +@git checkout -- /path/to/dir@ + +Dieser Befehl wird das Verzeichnis @/path/to/dir@ aus dem angegebenen "treeish" wiederherstellen. Wir gehen durch ein entsprechendes Beispiel: + +Zunächst entfernen wir ein Verzeichnis und führen dann eine ganze Menge von Änderungen zusammen (zur künftigen Referenz, das Beispiel stammt aus einem Refactoring-Zweig von "Jekyll":http://github.com/qrush/jekyll, die statische Blog-Engine für diese Seite). + +p=. !/images/checkout1.png! + +Die Historie sieht dann so aus: + +p=. !/images/checkout2.png! + +Das ist hoffentlich nicht zu verwirrend. Der Commit von eben ist vom Prinzip her ziemlich weit unten in der Historie und das entspricht meistens auch der Realität, wenn ein Verzeichnis wiederhergestellt werden soll. Als Erstes benötigen wir die Referenz des Commits, der das gewünschte Verzeichnis enthält. In unserem Fall ist bekannt, dass der letzte Commit der Merge war und im Commit vorher wurde das Verzeichnis gelöscht. Also ist der zu referenzierende Commit der dritte in der Historie, oder @HEAD~2@. Man könnte den Commit auch mit dem Branch-Namen referenzieren (@test~2@) oder sogar auf den SHA der Löschung zurück gehen (@f46666d^@). + +Wenn versucht wird, ein Verzeichnis aus einer Revision herauszuholen, das dort nicht existiert, kommt in jedem Fall diese nette Nachricht: + +
+$ git checkout test~1 -- bin/
+error: pathspec 'bin' did not match any file(s) known to git.
+
+ +Wird die richtige Revision verwendet, kommt auch das Verzeichnis zurück, wo es hingehört: + +p=. !/images/checkout3.png! + +Großartig, nun sind wir wieder im Geschäft. Von hier kann man Dateien oder das Verzeichnis wie gewünscht hinzufügen und einchecken. + +In dieser Situation kommt eventuell auch das Zurückrollen (Revert) das Commits in Frage, das ebenso gelöschte Dateien wiederherstellt. Das ist jedoch nicht immer möglich und muss nicht der beste Weg sein, ein vermisstes Verzeichnis aus der Historie zurückzuholen. diff --git a/_posts/2009-03-20-reorder-commits-with-rebase.textile b/_posts/2009-03-20-reorder-commits-with-rebase.textile new file mode 100644 index 0000000..0cd4e6d --- /dev/null +++ b/_posts/2009-03-20-reorder-commits-with-rebase.textile @@ -0,0 +1,49 @@ +--- +layout: post +title: Commits mit Rebase neu Anordnen +category: advanced +published: true +--- + +Ein der weitesgehenden Verwendungen von "git rebase -i":http://de.gitready.com/intermediate/2009/01/31/intro-to-rebase.html ist das Neuordnen von Commits. Aber bitte, BITTE verwendet rebase nicht bei Commits, die bereits öffentlich verteilt worden sind. Wenn du mit anderen Entwicklern zusammenarbeitest, führt das zu Merges, nicht mehr als fast-forward zusammengeführt werden können und das bedeutet meist Kopfschmerzen für alle Beteiligten. Ja, der Befehlt erlaubt es, die Historie umzuschreiben und sollte nur durchgeführt werden, wenn die Commits noch nur auf dem lokalen System liegen. + +Das war es mit den Warnungen und wir kommen zum Punkt. Das Szenario handelt davon, dass die Reihenfolge von Commits geändert werden soll. Vielleicht sollen bestimmte Änderungen weiter unten in der Historie erscheinen oder aus irgend einem Grund macht der dritte Commit an der ersten Stelle einfach mehr Sinn. Das wollen wir jetzt einfach mal machen. Angenommen, unsere Historie sieht wie folgt aus: + +p=. !/images/reorder1.png! + +Wir fangen mit @git rebase -i HEAD~3@ an. Der $EDITOR öffnet sich mit ungefähr dem folgenden Text: + +
+pick 4c39bca gemspec tweak
+pick 85409cf Version bump to 0.4.1
+pick eb32194 Regenerated gemspec for version 0.4.1
+
+# Rebase 60709da..eb32194 onto 60709da
+#
+# Commands:
+#  p, pick = use commit
+#  e, edit = use commit, but stop for amending
+#  s, squash = use commit, but meld into previous commit
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+# However, if you remove everything, the rebase will be aborted.
+#
+
+ +Neu Anordnen ist so einfach wie die unterschiedlichen 'pick' Befehle herumzubewegen. Wenn der erste mit dem letzten Commit getauscht werden soll, sieht das so aus: + +
+pick eb32194 Regenerated gemspec for version 0.4.1
+pick 85409cf Version bump to 0.4.1
+pick 4c39bca gemspec tweak
+...
+
+$ git rebase -i HEAD~3
+Successfully rebased and updated refs/heads/test.
+
+ +Nach dem Speichern der Datei wird hoffentlich alles glatt gehen. Wenn nicht, gibt es wahrscheinlich einen netten Merge, der versorgt werden muss. Wenn es zu häßlich wird, sich darum zu kümmern, führt ein @git rebase --abort@ zum Ausgangspunkt zurück. Keine Sorge bezüglich Datenverlusten, da "reflog":http://de.gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html immer zur Seite steht, um alles zurückzuholen, was benötigt werden könnte. Wie erwartet, zeigt die Historie die Commits in umgedrehter Reihenfolge. + +p=. !/images/reorder2.png! + +Ein kurzer Hinweis: Das Datum der einzelnen Commits ist noch im Original vorhanden, d.h. nicht umgedreht. Insbesondere für andere Mitarbeiter am Repository kann das ein wenig komisch aussehen. Neu Anordnen ist wahrscheinlich nützlicher, sobald es mit anderen Aufgaben aus dem interaktiven Rebase kombiniert wird, z.B. "Squashing":http://de.gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html oder Commit-Nachrichten bearbeiten. Wenn das Neu Anordnen geholfen (oder auch geschmerzt) hat, lass es in den Kommentaren wissen. diff --git a/_posts/2009-03-23-whats-inside-your-git-directory.textile b/_posts/2009-03-23-whats-inside-your-git-directory.textile new file mode 100644 index 0000000..fdaae36 --- /dev/null +++ b/_posts/2009-03-23-whats-inside-your-git-directory.textile @@ -0,0 +1,74 @@ +--- +layout: post +title: Was in deinem .git Verzeichnis ist +category: advanced +published: true +--- + +*UPDATE*: Ich habe ein paar hilfreiche Kommentare mit Korrekturen für einige Dateien und was sie tun erhalten. Danke für's Weitergeben. + +Einige der Dinge, die ich an Git am meisten mag, ist die Tatsache, dass Git alle seine Informationen an einem Ort aufbewahrt: Das @.git@ Verzeichnis an der Wurzel des Projektverzeichnisses. Wenn du es noch nicht durchgewühlt hast, brauchst du dich darüber nicht ärgern! Darin gibt es ein paar nette Sahnehäubchen. Wir schauen uns die wichtigen Dateien und Verzeichnisse an und versuchen ein besseres Verständnis darüber zu bekommen, was unter der Haube vor sich geht. + +Die grundlegende Struktur sieht wie folgt aus: + +
+.
+|-- COMMIT_EDITMSG
+|-- FETCH_HEAD
+|-- HEAD
+|-- ORIG_HEAD
+|-- branches
+|-- config
+|-- description
+|-- hooks
+|   |-- applypatch-msg
+|   |-- commit-msg
+|   |-- post-commit
+|   |-- post-receive
+|   |-- post-update
+|   |-- pre-applypatch
+|   |-- pre-commit
+|   |-- pre-rebase
+|   |-- prepare-commit-msg
+|   `-- update
+|-- index
+|-- info
+|   `-- exclude
+|-- logs
+|   |-- HEAD
+|   `-- refs
+|-- objects
+`-- refs
+    |-- heads
+    |-- remotes
+    |-- stash
+    `-- tags
+
+ +Wir gehen über ein paar normale Dateien, die sich im Hauptverzeichnis befinden: + +* @COMMIT_EDITMSG@: Das ist die letzte Commit-Nachricht. Sie wird von Git überhaupt nicht verwendet, befindet sich aber hier aus Gründen der Referenz für dich. +* @config@: Enthält die Einstellungen für dieses Repository. Spezifische Konfigurationsvariablen können hier untergebracht werden (und sogar "Aliase":http://de.gitready.com/intermediate/2009/02/06/helpful-command-aliases.html). Diese Datei wird vor allem dazu genutzt, den Ort entfernter Branches zu hinterlegen und ein paar Kerneinstellungen zu speichern, z.B. ob das Repository blank ist oder nicht. +* @description@: Wenn "gitweb":http://git.or.cz/gitwiki/Gitweb verwendet oder @git instaweb@ gestartet werden, wird diese Beschreibung bei der Ansicht des Repositorys oder in der Listenansicht aller Repositories angezeigt. +* @FETCH_HEAD@: Die SHA-Hashes der Branch- oder Remote-Heads, die während des letzten @git fetch@ aktualisiert worden sind. +* @HEAD@: Die aktuelle Referenz auf die Revision, die betrachtet wird. In den meisten Fällen ist das wahrscheinlich @refs/heads/master@. +* @index@: Der "Staging Bereich":http://de.gitready.com/beginner/2009/01/18/the-staging-area.html mit Metadaten wie Zeitstempel, Dateinamen und SHA-Hashes von Dateien, die bereits von Git aufgenommen wurden. +* @packed-refs@: Verpackt ruhende Referenzen. Das ist keine endgültige Liste von Referenzen im Repository (Das @refs@ Verzeichnis hat die echten Referenzen!). Wirf einen Blick auf gitsters Kommentar, um mehr Informationen darüber zu lesen. +* @ORIG_HEAD@: Bei einem Merge ist das der SHA-Hash des Branches, in den gemerged wird. +* @MERGE_HEAD@: Bei einem Merge ist das der SHA-Hash des Branches, von dem gemerged wird. +* @MERGE_MODE@: Wird zum Kommunizieren von Beschränkung verwendet, die ursprünglich an @git merge@ und weiter an @git commit@ bei Merge-Konflikten übergeben wurden, und wo ein separater @git commit@ zum Abschließen der Aktion notwendig ist. Momentan ist @--no-ff@ die einzige auf diese Weise übergebene Beschränkung. +* @MERGE_MSG@: Zählt die Konflikte auf, die während des aktuellen Merges aufgetreten sind. +* @RENAMED-REF@: Ich versuche das hier immer noch zu erschließen. Nach einem einfachen Grep durch den Quellcode sieht es so aus, dass diese Datei mit Fehlern beim Speichern von Referenzen im Zusammenhang steht. + +Es gibt auch eine ganze Reihe von Verzeichnissen: + +* @hooks@: Ein Verzeichnis, das schnell ein guter Freund werden wird. Es beinhaltet Scripte, die zu bestimmten Zeitpunkten bei der Arbeit mit Git ausgeführt werden, z.B. nach einem Commit oder vor einem Rebase. Eine ganze Artikelserie zu diesen Hooks ist geplant. +* @info@: Relativ uninteressant bis auf die Datei @exclude@, die sich darin befindet. Wir haben sie bereits bei "Ignorieren von Dateien":http://de.gitready.com/beginner/2009/01/19/ignoring-files.html gesehen. Aber als Erinnerung, man kann diese Datei zum Ignorieren von Dateien im Projekt verwenden. Aber Vorsicht, sie wird nicht wie @.gitignore@ versioniert. +* @logs@: Beinhaltet die Historie der unterschiedlichen Branches. Wird offensichtlich am meisten mit dem "reflog-Befehl":http://de.gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html verwendet. +* @objects@: Gits internes Warenlager von Binärobjekten, die alle mit SHA-Hashes indiziert sind. +* @rebase-apply@: Die Werkbank für "Rebase":http://de.gitready.com/intermediate/2009/01/31/intro-to-rebase.html und für @git am@. Wenn du mutig bist, kannst du in die @patch@ Datei eintauchen, wenn ein Patch nicht sauber angewendet wird. +* @refs@: Die Master-Kopie aller Referenzen, die in deinem Repository liegen, seien es Stashes, Tags, remote-tracking Branches oder lokale Branches. + +Nur ein Wort der Weisheit, wenn es um das Wildern im Innenleben von Git geht: Stell sicher, dass du weißt, was du tust. Falls nicht, mache vorher ein Backup. Mit den Konfigurationsdateien und den Hooks herumhantieren ist recht einfach. Aber ich würde nicht im Datenspeicher herumwühlen, wenn ich nicht muss. + +Es gibt noch mehr über das Innenleben von Git zu sagen, dass wir bisher noch nicht abgedeckt haben. Eine der besten Anleitungen ist das "Git Community Book":http://book.git-scm.com, und natürlich kannst du dir den "Quellcode selbst herunterladen":http://git.kernel.org/?p=git/git.git;a=summary und einen Blick hinein werfen. Wenn du noch mehr Informationen über das Innenleben des @.git@ Verzeichnisses hast, lass es uns in den Kommentaren wissen. diff --git a/_posts/2009-04-03-find-ancestor-commits.textile b/_posts/2009-04-03-find-ancestor-commits.textile new file mode 100644 index 0000000..ebcb13e --- /dev/null +++ b/_posts/2009-04-03-find-ancestor-commits.textile @@ -0,0 +1,66 @@ +--- +layout: post +title: Vorfahren von Commits finden +category: intermediate +published: true +--- + +Schonmal diese Nachrichte beim Löschen eines Branches gesehen? + +
+$ git branch -d docs
+error: The branch 'docs' is not an ancestor of your current HEAD.
+If you are sure you want to delete it, run 'git branch -D docs'
+
+ +Der gegenwärtige Branch beinhaltet den zu löschenden Branch nicht, weil er noch nicht gemerged wurde. Die Nachricht zeigt, wie hartnäckig Git sich darum kümmert, dass keine Daten verloren gehen. Wie kann man also herausfinden, ob ein gegebener Branch (oder Commit) in den aktuellen Branch gemerged wurde, ohne einen Löschversuch zu unternehmen? + +Der @git branch@ Befehl hat ein paar Optionen, die bei der Lösung dieses Problems helfen. Die Option @--contains@ findet heraus, ob ein bestimmter Commit bereits in den aktuellen Branch eingebracht wurde. Vielleicht gibt es einen Commit-Hash von einem Patch, bei dem angenommen wurde, er sei bereits eingebracht. Oder man möchte herausfinden, ob der Commit für das Open Source Lieblingsprojekt, das den Speicherverbrauch um 75% senkt, bereits übernommen wurde. + +
+$ git log -1 tests
+commit d590f2ac0635ec0053c4a7377bd929943d475297
+Author: Nick Quaranto 
+Date:   Wed Apr 1 20:38:59 2009 -0400
+
+    Green all around, finally.
+
+$ git branch --contains d590f2
+  tests
+* master
+
+ +Das Ergebnis zeigt, dass der Commit @d590f2@ in die Branches @tests@ und @master@ übernommen wurde. + +Zurück zu unserem anfänglichen Rätsel: Wie findet man heraus, ob ein Branch bereits gemerged wurde? Die Optionen @--merged@ und @--no-merged@ kümmern sich genau darum. Die erste Option verrät, in welche Branches der "treeish":http://book.git-scm.com/4_git_treeishes.html bereits gemerged wurde. Die zweite Option verrät genau das Gegenteil, welche Branches den treeish noch nicht gemerged haben. + +In diesem Fall, unser @docs@ Branch ist nicht vollständig in den @master@ Branch gemerged: + +
+$ git branch --merged docs
+  docs
+
+$ git branch --no-merged docs
+  config
+* master
+  tests
+
+$ git branch -d docs
+error: The branch 'docs' is not an ancestor of your current HEAD.
+If you are sure you want to delete it, run 'git branch -D docs'.
+
+$ git branch -D docs
+Deleted branch docs (884583c).
+
+ +Wenn du mutig bist, könntest du eine Kombination aus @git rev-parse@ und @git rev-list@ verwenden, um herauszufinden, ob ein Commit in der Historie eines gegebenen Branches vorhanden ist oder nicht. Ich hatte mir das so bereits zusammengehackt, bis mich jemand im "#git IRC Channel":http://de.gitready.com/beginner/2009/03/02/where-to-find-the-git-community.html auf die offensichtliche Lösung mit @git branch@ brachte. @rev-parse@ nimmt den treeish und konvertiert ihn in den dazu gehörigen SHA-Hash. @rev-list@ kann Commits in Myriaden von unterschiedlichen Wegen ausgeben und verdient einen eigenen Tipp. + +
+$ git rev-list master | grep $(git rev-parse docs)
+$ git rev-list master | grep $(git rev-parse tests)
+d590f2ac0635ec0053c4a7377bd929943d475297
+
+ +Der erste Befehl gibt gar nichts zurück, weil der @HEAD@ Commit aus dem @docs@ Branch noch nicht in der Historie des @master@Branches existiert. Andererseits findet grep wie erwartet den @HEAD@ Commit aus dem @tests@ Branch im @master@ Branch. + +Hoffentlich spart dir das etwas Zeit, wenn du mit mehreren Branches hantierst und dich fragst, ob die Branches bereits gemerged wurden. Wenn du andere Vorschläge für den Umgang mit solchen Situationen hast, hinterlasse einen Kommentar. diff --git a/_posts/2009-04-16-find-unmerged-commits.textile b/_posts/2009-04-16-find-unmerged-commits.textile new file mode 100644 index 0000000..ad51845 --- /dev/null +++ b/_posts/2009-04-16-find-unmerged-commits.textile @@ -0,0 +1,62 @@ +--- +layout: post +title: Unmerged Commits finden +category: intermediate +published: true +--- + +Du hast dich in einem thematischen Branch (Zweig) bei der Entwicklung deiner Software voran gearbeitet und es ist an der Zeit, deine Arbeit in die Hauptentwicklungslinie zu mergen. Mit grafischen Ansichten wie "gitk oder GitX":http://de.gitready.com/intermediate/2009/01/13/visualizing-your-repo.html ist es recht einfach heraus zu finden, welche Changesets noch zu mergen sind. Stellen wir uns folgendes Szenario vor: + +p=. !/images/cherry-gitx.png! + +Auf der Kommandozeile hast du ein paar Optionen. Eine anständige Art der Visualisierung eröffnet sich bei der Verwendung von @git log@, dass neben der folgenden "eine Menge Optionen":http://de.gitready.com/advanced/2009/01/20/bend-logs-to-your-will.html anbietet: + +@git log --pretty=oneline --graph --all@ + +p=. !/images/cherry-log.png! + +Du kannst auch die Bereichssyntax in @git log@ verwenden, um jene Commits zu bekommen, die noch nicht zusammengeführt sind. + +
+$ git checkout master
+$ git log ..42-adding-replies
+
+ +@git log master..42-adding-replies@ + +Es gibt noch eine weitere Möglichkeit: @git cherry@. Sie macht genau, was wir wollen und sagt uns, welche Commits noch nicht im genannten Branch sind. Im Master-Branch führe ich folgenden Befehl aus: + +
+$ git cherry -v master 42-adding-replies
++ a4d0f79fccbbc12a53e8f0e5c2a4ef960ad69ba2 Adding posts in
++ 7e71afd1faf36f17a0ff506e63cd2ca51496dad3 Revert "Adding posts in"
++ 5e815ece05d8813354e60ca1affb8cdb8c5d78fc Adding the right model
++ 956f4cec5684544066a0d261ff8ac80aff7a57ea Cleaning up model
++ 6c6cdb4342ed935f8fbd38f48f51dec469dd1823 Who needs tests?
++ c3481fd0d6279f5bd45c455b915e0b4b1c0d8909 Wrapping this up. Ship it.
+
+ +Wir haben soeben Git gefragt, was nicht im @master@, aber im @42-adding-replies@-Branch ist. Wie in den Abbildungen oben sehen wir, was noch zu mergen ist. Die @-v@ Option gibt die Commit Nachricht zusammen mit dem SHA Hash aus. Der Befehl nimmt auch ein drittes, optionales Argument für einen Startpunkt oder eine Grenze auf. Wenn wir alles nach dem Commit @7e71af@ überprüfen wollen, nehmen wir: + +
+$ git cherry -v master 42-adding-replies 7e71af
++ 5e815ece05d8813354e60ca1affb8cdb8c5d78fc Adding the right model
++ 956f4cec5684544066a0d261ff8ac80aff7a57ea Cleaning up model
++ 6c6cdb4342ed935f8fbd38f48f51dec469dd1823 Who needs tests?
++ c3481fd0d6279f5bd45c455b915e0b4b1c0d8909 Wrapping this up. Ship it.
+
+ +Wie du sehen kannst, wurden die ersten beiden Commits in unserem Themenzweig ausgelassen. Wenn du überprüfen möchtest, was nicht im Upstream-Branch ist, wenn du dich nicht im Upstream-Branch befindest, ist es wieder einfacher: + +
+$ git checkout 42-adding-replies
+$ git cherry master
++ a4d0f79fccbbc12a53e8f0e5c2a4ef960ad69ba2
++ 7e71afd1faf36f17a0ff506e63cd2ca51496dad3
++ 5e815ece05d8813354e60ca1affb8cdb8c5d78fc
++ 956f4cec5684544066a0d261ff8ac80aff7a57ea
++ 6c6cdb4342ed935f8fbd38f48f51dec469dd1823
++ c3481fd0d6279f5bd45c455b915e0b4b1c0d8909
+
+ +Ein wirklich nützlicher Aspekt des Befehls besteht darin, dass er wirklich die Changesets anstatt nur die SHAs vergleicht. Der Commit könnte sich durch Hinzufügen einer Signatur oder auch im Elternknoten verändert haben. In jedem Fall kannst du dich auf den Befehl verlassen. Er sagt dir, was noch nicht in den Upstream-Branch überführt wurde. Verwechsle den Befehl nicht mit "cherry-pick":http://de.gitready.com/intermediate/2009/03/04/pick-out-individual-commits.html, der etwas ganz anderes macht. diff --git a/_posts/2009-07-31-tig-the-ncurses-front-end-to-git.textile b/_posts/2009-07-31-tig-the-ncurses-front-end-to-git.textile new file mode 100644 index 0000000..f648640 --- /dev/null +++ b/_posts/2009-07-31-tig-the-ncurses-front-end-to-git.textile @@ -0,0 +1,26 @@ +--- +layout: post +title: tig, das NCurses Frontend für Git +category: advanced +published: true +--- + +p=. Das ist ein Gastbeitrag von "Nathan de Vries":http://www.atnan.com/. + +Ich war nie ein Fan von gitk, aber als ich anfing, Git zu benutzen, fand ich ein Werkzeug namens "tig":http://jonas.nitro.dk/tig/. Es ist in den "MacPorts":http://tig.darwinports.com/ und in Ubuntu (seit Gutsy) mit @apt-get install tig@ verfügbar. Tig bietet eine einfache Kommandozeile und ist doch eine graphische Schnittstelle zu Git. + +p=. "!/images/main-view-split.png(Die geteilte Hauptansicht - Oben das Protokoll, Unten die Unterschiede)!":http://jonas.nitro.dk/tig/screenshots/main-view-split.png + +Tig wird am einfachsten im Git Repository mit @tig@ gestartet. Die graphische Git-Log-Ansicht startet und du kannst mit den Pfeiltasten nach unten und oben durch das Protokoll navigieren (oder mit den @j@ und @k@ Tasten, wenn du die VIM Tastenkürzel gewöhnt bist). @@ auf einen Logeintrag öffnet ein geteiltes Fenster mit dem Diff dieses Commits. Die @@ bewegt dich durch das Diff und die Pfeiltasten bewegen dich zwischen den Commits hindurch. @q@ schließt das geteilte Fenster und nochmal @q@ beendet tig. + +Ein weiteres Feature von tig ist die Baumansicht. Nach dem Start von tig öffnet @t@ in der Log-Ansicht eine navigierbare Dateiansicht des Repositorys. @@ bringt dich durch Verzeichnisse oder Dateien. @-B@ auf eine Datei zeigt die Annotated-Ansicht. + +p=. "!/images/tree-view.png(Die Baumansicht)!":http://jonas.nitro.dk/tig/screenshots/tree-view.png + +Bisher haben wir tig nur für den Branch verwendet, den wir vorher ausgewählt hatten. Aber tig versteht auch Revisionsargumente wie Branch, Tag oder Hash, etc. Ich persönlich finde das sehr nützlich, weil damit die Aktivitäten in einem entfernten Branch verfolgt werden können. Der Befehl hierfür könnte so aussehen @tig origin/rel-1.5@. + +Einen Branch aus einem anderen Branch heraus anzusehen, kann auch nützlich sein, wenn einzelne "Commits übernommen (cherry-pick)":http://de.gitready.com/intermediate/2009/03/04/pick-out-individual-commits.html werden sollen. Nehmen wir an, ich habe einen Commit in @master@ vorgenommen, die ich im Release-Branch @origin/rel-1.5@ verfügbar machen möchte. Ich muss lediglich den Release-Branch mit @git checkout -b 1.5 origin/rel-1.5@ auschecken, tig mit @tig master@ öffnen und zu dem Changeset navigieren, das ich gerne mit @-C@ übernehmen möchte. Wiederhole diesen Schritt so oft, wie nötig. + +p=. "!/images/blame-view.png(Die Schuldansicht)!":http://jonas.nitro.dk/tig/screenshots/blame-view.png + +Ich konnte noch nicht alle anderen Features von tig untersuchen, bis auf @tig show [rev]@ und @tig blame [file]@, die ich jeden Tag benutze. Wenn du weitere Tips für die Benutzung von tig hat, lass sie uns bitte in den Kommentaren wissen! diff --git a/about.html b/about.html new file mode 100644 index 0000000..1b4ae41 --- /dev/null +++ b/about.html @@ -0,0 +1,35 @@ +--- +layout: default +title: Über Gitready +--- +
+

Über Gitready

+

+ Wenn du nach Hinweisen zur Verwendung von Git suchst, bist du hier richtig! + Diese Seite beschäftigt sich damit, Git für den Anfänger besser verwendbar zu + machen und jenen, die bereits mit Git vertraut sind, ein paar neue Tricks zu + zeigen. +

+

+ Du willst das Layout, Design oder etwas anders ändern? Besuche die + Projektseite auf Github. + Du willst deinen Tip hier sehen? Sende ihn hier ein. +

+

+ Du möchtest den Autor erreichen? Sende ihm eine E-Mail an nick@quaran.to, + schau auf Twitter vorbei, oder + schreibe ihn auf GitHub an. +

+

+ Ein Haftungsausschluß zu den Tips: Der Autor beansprucht nicht + fehlerfrei oder anderweitig perfekt in seinen Git-Fähigkeiten zu sein. Der + Hauptgrund für dieses Blog war, mehr über Git und seine Arbeitsweise zu + lernen. Es ist ein Lernprozess für alle Beteiligten und darum ist es wertvoll + für die Leser und den Autor. Solltest du Fehler und Ungenauigkeiten + finden, zögere bitte nicht Nick zu kontaktieren oder einen Kommentar zu + hinterlassen. +

+

+ Und schließlich... danke für das Lesen! +

+
diff --git a/atom.xml b/atom.xml new file mode 100644 index 0000000..c4036d1 --- /dev/null +++ b/atom.xml @@ -0,0 +1,27 @@ +--- +layout: nil +--- + + + + Git Ready + + + {{ site.time | date_to_xmlschema }} + http://gitready.com/ + + Nick Quaranto + nick@quaran.to + + + {% for post in site.posts %} + + {{ post.title }} + + {{ post.date | date_to_xmlschema }} + http://gitready.com{{ post.id }} + {{ post.content | xml_escape }} + + {% endfor %} + + diff --git a/css/960.css b/css/960.css new file mode 100644 index 0000000..dac2d0d --- /dev/null +++ b/css/960.css @@ -0,0 +1 @@ +.container_12,.container_16{margin-left:auto;margin-right:auto;width:960px}.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12,.grid_13,.grid_14,.grid_15,.grid_16{display:inline;float:left;margin-left:10px;margin-right:10px}.container_12 .grid_3,.container_16 .grid_4{width:220px}.container_12 .grid_6,.container_16 .grid_8{width:460px}.container_12 .grid_9,.container_16 .grid_12{width:700px}.container_12 .grid_12,.container_16 .grid_16{width:940px}.alpha{margin-left:0}.omega{margin-right:0}.container_12 .grid_1{width:60px}.container_12 .grid_2{width:140px}.container_12 .grid_4{width:300px}.container_12 .grid_5{width:380px}.container_12 .grid_7{width:540px}.container_12 .grid_8{width:620px}.container_12 .grid_10{width:780px}.container_12 .grid_11{width:860px}.container_16 .grid_1{width:40px}.container_16 .grid_2{width:100px}.container_16 .grid_3{width:160px}.container_16 .grid_5{width:280px}.container_16 .grid_6{width:340px}.container_16 .grid_7{width:400px}.container_16 .grid_9{width:520px}.container_16 .grid_10{width:580px}.container_16 .grid_11{width:640px}.container_16 .grid_13{width:760px}.container_16 .grid_14{width:820px}.container_16 .grid_15{width:880px}.container_12 .prefix_3,.container_16 .prefix_4{padding-left:240px}.container_12 .prefix_6,.container_16 .prefix_8{padding-left:480px}.container_12 .prefix_9,.container_16 .prefix_12{padding-left:720px}.container_12 .prefix_1{padding-left:80px}.container_12 .prefix_2{padding-left:160px}.container_12 .prefix_4{padding-left:320px}.container_12 .prefix_5{padding-left:400px}.container_12 .prefix_7{padding-left:560px}.container_12 .prefix_8{padding-left:640px}.container_12 .prefix_10{padding-left:800px}.container_12 .prefix_11{padding-left:880px}.container_16 .prefix_1{padding-left:60px}.container_16 .prefix_2{padding-left:120px}.container_16 .prefix_3{padding-left:180px}.container_16 .prefix_5{padding-left:300px}.container_16 .prefix_6{padding-left:360px}.container_16 .prefix_7{padding-left:420px}.container_16 .prefix_9{padding-left:540px}.container_16 .prefix_10{padding-left:600px}.container_16 .prefix_11{padding-left:660px}.container_16 .prefix_13{padding-left:780px}.container_16 .prefix_14{padding-left:840px}.container_16 .prefix_15{padding-left:900px}.container_12 .suffix_3,.container_16 .suffix_4{padding-right:240px}.container_12 .suffix_6,.container_16 .suffix_8{padding-right:480px}.container_12 .suffix_9,.container_16 .suffix_12{padding-right:720px}.container_12 .suffix_1{padding-right:80px}.container_12 .suffix_2{padding-right:160px}.container_12 .suffix_4{padding-right:320px}.container_12 .suffix_5{padding-right:400px}.container_12 .suffix_7{padding-right:560px}.container_12 .suffix_8{padding-right:640px}.container_12 .suffix_10{padding-right:800px}.container_12 .suffix_11{padding-right:880px}.container_16 .suffix_1{padding-right:60px}.container_16 .suffix_2{padding-right:120px}.container_16 .suffix_3{padding-right:180px}.container_16 .suffix_5{padding-right:300px}.container_16 .suffix_6{padding-right:360px}.container_16 .suffix_7{padding-right:420px}.container_16 .suffix_9{padding-right:540px}.container_16 .suffix_10{padding-right:600px}.container_16 .suffix_11{padding-right:660px}.container_16 .suffix_13{padding-right:780px}.container_16 .suffix_14{padding-right:840px}.container_16 .suffix_15{padding-right:900px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:after{clear:both;content:'.';display:block;visibility:hidden;height:0}.clearfix{display:inline-block}* html .clearfix{height:1%}.clearfix{display:block} \ No newline at end of file diff --git a/css/reset.css b/css/reset.css new file mode 100755 index 0000000..99a0211 --- /dev/null +++ b/css/reset.css @@ -0,0 +1 @@ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0} \ No newline at end of file diff --git a/css/screen.css b/css/screen.css new file mode 100644 index 0000000..5e4f20d --- /dev/null +++ b/css/screen.css @@ -0,0 +1,296 @@ +body { + background-color: white; + font: 13.34px Verdana, helvetica, arial, clean, sans-serif; + *font-size: small; + background: #222; +} + +iframe { + margin: 0 15px; +} + +a { + color: #8A003D; + text-decoration: none; +} + +.content p a, .content ul a { + color: #000; + background: #AED180; +} + +.content p a:hover, .content ul a:hover { + color: #fff; + background: #000; +} + +a:visited { +} + +p { + text-align: left; + padding: 8px 15px; + line-height: 19px; +} + +#disqus { background: #DEE6CF; padding: 10px; } +#dsq-content { width: 575px; } +#date { text-align: center; color: #333; font-size: 80%;} +#post img { padding: 10px; border: 2px solid #aaa; background: #eee; } +#feedburner { + position: fixed; + bottom: 0; + left: 0; + margin: 0; +} + +#counter { margin-left: 425px; } + + +/*****************************************************************************/ +/* +/* Home +/* +/*****************************************************************************/ + +.recent { + list-style-type: square; + list-style-position: outside; + color: #FFFEE6; + padding-left: 9px; + font-size: 95%; + text-align: left; +} + + .recent li { + margin-bottom: 5px; + } + + .recent a{ color: #AED180; } + .recent a:hover { color: #FFE3A3; text-decoration: underline; background: none; } + + ul.posts span { + font-family: Monaco, "Courier New", monospace; + font-size: 80%; + } + +/*****************************************************************************/ +/* +/* Site +/* +/*****************************************************************************/ + + +.title { + margin: 20px 0; +} + +.title h1 { + display:inline; +} + +.title h1 a { + color: #92BF6F; + font-weight: bold; + margin-bottom: 20px; + font-size: 50px; + font-family: "Consolas", "Monaco", "Courier New", "Courier", monospace; +} + +.info div { + text-align: right; +} + +.info .extra { + color: #aaa; + text-decoration: none; + margin-top: 35px; + font-size: 16px; +} + +.info .author { + color: #fff; + font-size: 11px; + margin-top: 5px; +} + +.content { + background: #FFFEE6; +} + +.white { + background: #FFFFFF; +} + +.links a, .links a:hover { + color: #000; + text-align: center; + font-size: 80%; + display: block; + padding: 3px; + background: #FFE3A3; +} + +.links h3 { + text-align: center; + font-size: 11px +} + +.links a:hover +{ + background: #AED180; +} + +h2{ + padding: 10px; + font-size: 21px; + font-weight: normal; + text-align: left; + border-bottom: 2px solid #333; + margin: 10px 15px; +} + +h2 a { color: #000; } + +h3{ + font-family: "Consolas", "Monaco", "Courier New", "Courier", monospace; + padding: 10px; + font-size: 15px; + font-weight: bold; + font-size: 16px; +} + +#post h3{ margin-left: 5px; } + + +#green { color: #99FF80; } +#red { color: #BF3030; } +#yellow { color: #B3B300; } +#blue { color: #809FFF; } +#purple { + text-align: center; + padding: 0 0 5px; + color: #FF80FF; +} + +.title a.extra:hover { +color: black; +} + +.meta { +color: #aaa; +} + +.footer { + color: #666; + margin-top: 1em; + overflow: hidden; + clear: both; + text-align: center; +} + +.footer a { + color: #AED180; + font-size: 16px; + display:inline-block; + padding: 10px; + font-family: "Consolas", "Monaco", "Courier New", "Courier", monospace; +} + +.footer a:hover { + color: #E3DF8A; + text-decoration: underline; +} + + +.footer .languages span, .footer .languages a { + padding: 0; + font-size: 12px; +} + +.footer .languages { + margin-bottom: 15px; +} +/*****************************************************************************/ +/* +/* Posts +/* +/*****************************************************************************/ + +#more { + margin: 10px 0; + padding: 3px; + display:block; + font-size: 13px; + font-weight: bold; } + + /* standard */ + + + blockquote{ + font: 14px/22px normal helvetica, sans-serif; + margin: 10px 50px; + padding-left: 10px; + padding-top: 10px; + padding-bottom: 10px; + border-left: 5px solid #ccc; + background-color: #eef; + } + blockquote p { margin: 0; padding: 0; } + pre { + border: 1px solid #ddd; + background-color: #eef; + padding: 0 .4em; + text-align: left; + font-size: 90%; + margin: 0 15px; + overflow: hidden; + } + + code { + border: 1px solid #ddd; + background-color: #eef; + font-size: 95%; + padding: 0 .2em; + } + + #post pre code { + border: none; + } + + /* terminal */ + + #post pre.terminal { + border: 1px solid black; + background-color: #333; + color: white; + } + + #post pre.terminal code { + background-color: #333; + } + +#post ul, #post ol { + list-style-type: disc; + text-align: left; + margin-left: 40px; +} + +#post li { margin-bottom: 3px; } + + +#related { + margin-top: 2em; +} + + #related h2 { + margin-bottom: 1em; + } + +.survey { + font-size: 90%; + text-align: center; + padding: 5px; + background: #AED180; + margin-bottom: 20px; +} diff --git a/css/text.css b/css/text.css new file mode 100755 index 0000000..b024b8c --- /dev/null +++ b/css/text.css @@ -0,0 +1 @@ +body{font:13px/1.5 Helvetica,Arial,'Liberation Sans',FreeSans,sans-serif}a:focus{outline:1px dotted invert}hr{border:0 #ccc solid;border-top-width:1px;clear:both;height:0}h1{font-size:25px}h2{font-size:23px}h3{font-size:21px}h4{font-size:19px}h5{font-size:17px}h6{font-size:15px}ol{list-style:decimal}ul{list-style:square}li{margin-left:30px}p,dl,hr,h1,h2,h3,h4,h5,h6,ol,ul,pre,table,address,fieldset{margin-bottom:20px} \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..e548500 Binary files /dev/null and b/favicon.ico differ diff --git a/images/blame-view.png b/images/blame-view.png new file mode 100644 index 0000000..7079410 Binary files /dev/null and b/images/blame-view.png differ diff --git a/images/branches.png b/images/branches.png new file mode 100644 index 0000000..26c49db Binary files /dev/null and b/images/branches.png differ diff --git a/images/checkout1.png b/images/checkout1.png new file mode 100644 index 0000000..8d6640a Binary files /dev/null and b/images/checkout1.png differ diff --git a/images/checkout2.png b/images/checkout2.png new file mode 100644 index 0000000..8b2b100 Binary files /dev/null and b/images/checkout2.png differ diff --git a/images/checkout3.png b/images/checkout3.png new file mode 100644 index 0000000..e0ffece Binary files /dev/null and b/images/checkout3.png differ diff --git a/images/cherry-gitx.png b/images/cherry-gitx.png new file mode 100644 index 0000000..26d3925 Binary files /dev/null and b/images/cherry-gitx.png differ diff --git a/images/cherry-log.png b/images/cherry-log.png new file mode 100644 index 0000000..156490c Binary files /dev/null and b/images/cherry-log.png differ diff --git a/images/conflicts.png b/images/conflicts.png new file mode 100644 index 0000000..bed6134 Binary files /dev/null and b/images/conflicts.png differ diff --git a/images/diff.png b/images/diff.png new file mode 100644 index 0000000..092b641 Binary files /dev/null and b/images/diff.png differ diff --git a/images/gitk.png b/images/gitk.png new file mode 100644 index 0000000..30529c4 Binary files /dev/null and b/images/gitk.png differ diff --git a/images/graph.png b/images/graph.png new file mode 100644 index 0000000..eeb64bc Binary files /dev/null and b/images/graph.png differ diff --git a/images/graphfail.png b/images/graphfail.png new file mode 100644 index 0000000..e70db76 Binary files /dev/null and b/images/graphfail.png differ diff --git a/images/grb1.png b/images/grb1.png new file mode 100644 index 0000000..b643157 Binary files /dev/null and b/images/grb1.png differ diff --git a/images/grb2.png b/images/grb2.png new file mode 100644 index 0000000..7734804 Binary files /dev/null and b/images/grb2.png differ diff --git a/images/impact.png b/images/impact.png new file mode 100644 index 0000000..9f0614d Binary files /dev/null and b/images/impact.png differ diff --git a/images/instaweb.png b/images/instaweb.png new file mode 100644 index 0000000..96d1b59 Binary files /dev/null and b/images/instaweb.png differ diff --git a/images/main-view-split.png b/images/main-view-split.png new file mode 100644 index 0000000..05a0ae4 Binary files /dev/null and b/images/main-view-split.png differ diff --git a/images/main-view.png b/images/main-view.png new file mode 100644 index 0000000..fe7030d Binary files /dev/null and b/images/main-view.png differ diff --git a/images/object1.png b/images/object1.png new file mode 100644 index 0000000..dd5afb5 Binary files /dev/null and b/images/object1.png differ diff --git a/images/object2.png b/images/object2.png new file mode 100644 index 0000000..1024fd7 Binary files /dev/null and b/images/object2.png differ diff --git a/images/object3.png b/images/object3.png new file mode 100644 index 0000000..8fe714f Binary files /dev/null and b/images/object3.png differ diff --git a/images/object4.png b/images/object4.png new file mode 100644 index 0000000..12dd948 Binary files /dev/null and b/images/object4.png differ diff --git a/images/object5.png b/images/object5.png new file mode 100644 index 0000000..99e4654 Binary files /dev/null and b/images/object5.png differ diff --git a/images/pick-cherry.png b/images/pick-cherry.png new file mode 100644 index 0000000..5d272a8 Binary files /dev/null and b/images/pick-cherry.png differ diff --git a/images/pick-merge.png b/images/pick-merge.png new file mode 100644 index 0000000..dcacd3d Binary files /dev/null and b/images/pick-merge.png differ diff --git a/images/pick.png b/images/pick.png new file mode 100644 index 0000000..ba6c8f7 Binary files /dev/null and b/images/pick.png differ diff --git a/images/pull1.png b/images/pull1.png new file mode 100644 index 0000000..147313c Binary files /dev/null and b/images/pull1.png differ diff --git a/images/pull2.png b/images/pull2.png new file mode 100644 index 0000000..755a4e6 Binary files /dev/null and b/images/pull2.png differ diff --git a/images/pull3.png b/images/pull3.png new file mode 100644 index 0000000..6178e4d Binary files /dev/null and b/images/pull3.png differ diff --git a/images/pull4.png b/images/pull4.png new file mode 100644 index 0000000..fbd88ae Binary files /dev/null and b/images/pull4.png differ diff --git a/images/punchcard.png b/images/punchcard.png new file mode 100644 index 0000000..45d4380 Binary files /dev/null and b/images/punchcard.png differ diff --git a/images/rebase1.png b/images/rebase1.png new file mode 100644 index 0000000..7702c27 Binary files /dev/null and b/images/rebase1.png differ diff --git a/images/rebase2.png b/images/rebase2.png new file mode 100644 index 0000000..68f1ce2 Binary files /dev/null and b/images/rebase2.png differ diff --git a/images/rebase3.png b/images/rebase3.png new file mode 100644 index 0000000..d19e5ff Binary files /dev/null and b/images/rebase3.png differ diff --git a/images/reflog-all.png b/images/reflog-all.png new file mode 100644 index 0000000..2b3a6c9 Binary files /dev/null and b/images/reflog-all.png differ diff --git a/images/reflog.png b/images/reflog.png new file mode 100644 index 0000000..ef1f285 Binary files /dev/null and b/images/reflog.png differ diff --git a/images/reorder1.png b/images/reorder1.png new file mode 100644 index 0000000..2cf4ef4 Binary files /dev/null and b/images/reorder1.png differ diff --git a/images/reorder2.png b/images/reorder2.png new file mode 100644 index 0000000..d2114bc Binary files /dev/null and b/images/reorder2.png differ diff --git a/images/revert1.png b/images/revert1.png new file mode 100644 index 0000000..e67f8ed Binary files /dev/null and b/images/revert1.png differ diff --git a/images/revert2.png b/images/revert2.png new file mode 100644 index 0000000..6b99715 Binary files /dev/null and b/images/revert2.png differ diff --git a/images/rss.png b/images/rss.png new file mode 100644 index 0000000..117886e Binary files /dev/null and b/images/rss.png differ diff --git a/images/squash1.png b/images/squash1.png new file mode 100644 index 0000000..e3bda4b Binary files /dev/null and b/images/squash1.png differ diff --git a/images/squash2.png b/images/squash2.png new file mode 100644 index 0000000..cf2aac7 Binary files /dev/null and b/images/squash2.png differ diff --git a/images/stump.png b/images/stump.png new file mode 100644 index 0000000..5a9d952 Binary files /dev/null and b/images/stump.png differ diff --git a/images/tag.png b/images/tag.png new file mode 100644 index 0000000..87f35e4 Binary files /dev/null and b/images/tag.png differ diff --git a/images/tree-view.png b/images/tree-view.png new file mode 100644 index 0000000..ad339d1 Binary files /dev/null and b/images/tree-view.png differ diff --git a/images/zsh-normal.png b/images/zsh-normal.png new file mode 100644 index 0000000..cc0d42e Binary files /dev/null and b/images/zsh-normal.png differ diff --git a/images/zsh-workflow.png b/images/zsh-workflow.png new file mode 100644 index 0000000..696189b Binary files /dev/null and b/images/zsh-workflow.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..a2f15df --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ +--- +layout: default +title: Lerne Git Commit für Commit +--- +{% assign first_post = site.posts.first %} +
+

+ Neuester Tip: {{ first_post.title }} +

+ {{ first_post.content | truncate: 450 }} + Mehr » +
+
+

Letzte Tips

+ +
diff --git a/submit.html b/submit.html new file mode 100644 index 0000000..2baf182 --- /dev/null +++ b/submit.html @@ -0,0 +1,8 @@ +--- +layout: default +title: Einen Tip einsenden! +--- +
+

Einen Tip einsenden!

+ +