diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..c1b1a0a70 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,64 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + + + + + + + + + + + + +**Which version of the book is affected?** + + + +**Describe the bug:** + + +**Steps to reproduce:** + + + + + + +**Expected behavior:** + + +**Screenshots:** + + +**Additional context:** + + + +**Desktop:** + + +- Operating system: +- Browser/application: +- Browser/application version: + +**Smartphone:** + + +- Device: +- OS: +- Browser/application: +- Browser/application version: + +**E-book reader:** + + +- Device: +- Software Update: diff --git a/.gitignore b/.gitignore index 5174165b7..724ad4412 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,4 @@ progit.pdfmarks progit.epub progit-kf8.epub progit.mobi -/images/ -*EN-DE.asc +contributors.txt diff --git a/.mailmap b/.mailmap new file mode 100644 index 000000000..d64acd787 --- /dev/null +++ b/.mailmap @@ -0,0 +1,2 @@ +Jean-Noël Avila +Scott Chacon \ No newline at end of file diff --git a/.tgitconfig b/.tgitconfig index 9a9773b33..a1a520376 100644 --- a/.tgitconfig +++ b/.tgitconfig @@ -1,6 +1,6 @@ [bugtraq] url = https://github.com/progit/progit2/issues/%BUGID% - logregex = "[Ii]ssues?:?(\\s*(,|and)?\\s*#?\\d+)+\n(\\d+)" + logregex = "(?:[Cc]lose[sd]?|[Ff]ix(?:e[sd])?|[Rr]esolve[sd]?):?\\s+(?:[Ii]ssues?\\s+#?|#)\\d+(?:(?:,|\\s+and)\\s+(?:[Ii]ssues?\\s+#?|#)\\d+)*\n(\\d+)" [tgit] icon = Pro.ico diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..17a10e01d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,33 @@ +language: ruby +git: + depth: false +cache: bundler +before_install: +- bundle install +after_success: +- script/tag_on_master +script: bundle exec rake book:build +env: + secure: "O+YCTDgLfCYAJjjOv2sApDRV5NJe6pkhiYIkORFuf2flO8HE72fEtDRpSWh1vulnIH6AjRK2jH7C8qA3MVbUO8D0io+Ha+vnbMXIp1JPCptcJNEkJrW13VTR66SWOzsgLp3mCrIC+YdE2JoYWGcnDsRMQwdnrWnxBzSOd22ZKzU=" + +before_deploy: bundle install && bundle exec rake book:build +deploy: + provider: releases + file: + - progit.epub + - progit.mobi + - progit.pdf + skip_cleanup: true + on: + tags: true + api-key: + secure: "l3XdupX6dT48IoTieJXrd7Yx8+KhiR2QYrNrDzT6RKxA7UyXGSP/axsVerg7OjKfIHWZgDJRVzcc2RswE+Xjw9sOY8r2h2q9uCwj8G0EqtFbtgGK0La5LB0euh0tNJN8GLFj1OdSZGY7dWWK88GXeHCua2WSify0V79R4ClIM+s=" +branches: + only: + - master + - /^2\.1(\.\d+)+$/ + +notifications: + email: + on_success: never + on_failure: always diff --git a/book/A-git-in-other-environments/1-git-other-environments.asc b/A-git-in-other-environments.asc similarity index 56% rename from book/A-git-in-other-environments/1-git-other-environments.asc rename to A-git-in-other-environments.asc index 911539045..496af0a65 100644 --- a/book/A-git-in-other-environments/1-git-other-environments.asc +++ b/A-git-in-other-environments.asc @@ -1,3 +1,4 @@ +[[A-git-in-other-environments]] [appendix] == Git in Other Environments @@ -6,18 +7,21 @@ You can work with local files, connect your repository to others over a network, But the story doesn't end there; Git is usually used as part of a larger ecosystem, and the terminal isn't always the best way to work with it. Now we'll take a look at some of the other kinds of environments where Git can be useful, and how other applications (including yours) work alongside Git. -include::sections/guis.asc[] +include::book/A-git-in-other-environments/sections/guis.asc[] -include::sections/visualstudio.asc[] +include::book/A-git-in-other-environments/sections/visualstudio.asc[] -include::sections/eclipse.asc[] +include::book/A-git-in-other-environments/sections/visualstudiocode.asc[] +include::book/A-git-in-other-environments/sections/eclipse.asc[] -include::sections/bash.asc[] +include::book/A-git-in-other-environments/sections/sublimetext.asc[] -include::sections/zsh.asc[] +include::book/A-git-in-other-environments/sections/bash.asc[] -include::sections/powershell.asc[] +include::book/A-git-in-other-environments/sections/zsh.asc[] + +include::book/A-git-in-other-environments/sections/powershell.asc[] === Summary diff --git a/B-embedding-git-in-your-applications.asc b/B-embedding-git-in-your-applications.asc new file mode 100644 index 000000000..782e177de --- /dev/null +++ b/B-embedding-git-in-your-applications.asc @@ -0,0 +1,20 @@ +[[B-embedding-git-in-your-applications]] +[appendix] +== Embedding Git in your Applications + +If your application is for developers, chances are good that it could benefit from integration with source control. +Even non-developer applications, such as document editors, could potentially benefit from version-control features, and Git's model works very well for many different scenarios. + +If you need to integrate Git with your application, you have essentially two options: spawn a shell and call the `git` command-line program, or embed a Git library into your application. +Here we'll cover command-line integration and several of the most popular embeddable Git libraries. + +include::book/B-embedding-git/sections/command-line.asc[] + +include::book/B-embedding-git/sections/libgit2.asc[] + +include::book/B-embedding-git/sections/jgit.asc[] + +include::book/B-embedding-git/sections/go-git.asc[] + +include::book/B-embedding-git/sections/dulwich.asc[] + diff --git a/book/C-git-commands/1-git-commands.asc b/C-git-commands.asc similarity index 54% rename from book/C-git-commands/1-git-commands.asc rename to C-git-commands.asc index 614aec8c5..04a5044d0 100644 --- a/book/C-git-commands/1-git-commands.asc +++ b/C-git-commands.asc @@ -1,3 +1,4 @@ +[[C-git-commands]] [appendix] == Git Commands @@ -21,24 +22,58 @@ There are several files this command will read from and write to so you can set The `git config` command has been used in nearly every chapter of the book. -In <<_first_time>> we used it to specify our name, email address and editor preference before we even got started using Git. +In <> we used it to specify our name, email address and editor preference before we even got started using Git. -In <<_git_aliases>> we showed how you could use it to create shorthand commands that expand to long option sequences so you don't have to type them every time. +In <> we showed how you could use it to create shorthand commands that expand to long option sequences so you don't have to type them every time. -In <<_rebasing>> we used it to make `--rebase` the default when you run `git pull`. +In <> we used it to make `--rebase` the default when you run `git pull`. -In <<_credential_caching>> we used it to set up a default store for your HTTP passwords. +In <> we used it to set up a default store for your HTTP passwords. -In <<_keyword_expansion>> we showed how to set up smudge and clean filters on content coming in and out of Git. +In <> we showed how to set up smudge and clean filters on content coming in and out of Git. -Finally, basically the entirety of <<_git_config>> is dedicated to the command. +Finally, basically the entirety of <> is dedicated to the command. + +[[_core_editor]] +==== git config core.editor commands + +Accompanying the configuration instructions in <>, many editors can be set as follows: + +.Exhaustive list of `core.editor` configuration commands +[cols="1,2",options="header"] +|============================== +|Editor | Configuration command +|Atom |`git config --global core.editor "atom --wait"` +|BBEdit (Mac, with command line tools) |`git config --global core.editor "bbedit -w"` +|Emacs |git config --global core.editor emacs +|Gedit (Linux) |`git config --global core.editor "gedit --wait --new-window"` +|Gvim (Windows 64-bit) |`git config --global core.editor "'C:/Program Files/Vim/vim72/gvim.exe' --nofork '%*'"` (Also see note below) +|Kate (Linux) |`git config --global core.editor "kate"` +|nano |`git config --global core.editor "nano -w"` +|Notepad (Windows 64-bit) |`git config core.editor notepad` +|Notepad++ (Windows 64-bit) |git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin" (Also see note below) +|Scratch (Linux)|`git config --global core.editor "scratch-text-editor"` +|Sublime Text (macOS) |`git config --global core.editor "/Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl --new-window --wait"` +|Sublime Text (Windows 64-bit) |`git config --global core.editor "'C:/Program Files/Sublime Text 3/sublime_text.exe' -w"` (Also see note below) +|Textmate |`git config --global core.editor "mate -w"` +|Textpad (Windows 64-bit) |`git config --global core.editor "'C:/Program Files/TextPad 5/TextPad.exe' -m` (Also see note below) +|Vim |`git config --global core.editor "vim"` +|VS Code |`git config --global core.editor "code --wait"` +|WordPad |`git config --global core.editor '"C:\Program Files\Windows NT\Accessories\wordpad.exe"'"` +|Xi | `git config --global core.editor "xi --wait"` +|============================== + +[NOTE] +==== +If you have a 32-bit editor on a Windows 64-bit system, the program will be installed in `C:\Program Files (x86)\` rather than `C:\Program Files\` as in the table above. +==== ==== git help The `git help` command is used to show you all the documentation shipped with Git about any command. While we're giving a rough overview of most of the more popular ones in this appendix, for a full listing of all of the possible options and flags for every command, you can always run `git help `. -We introduced the `git help` command in <<_git_help>> and showed you how to use it to find more information about the `git shell` in <<_setting_up_server>>. +We introduced the `git help` command in <> and showed you how to use it to find more information about the `git shell` in <>. === Getting and Creating Projects @@ -50,13 +85,13 @@ One is to copy it from an existing repository on the network or elsewhere and th To take a directory and turn it into a new Git repository so you can start version controlling it, you can simply run `git init`. -We first introduce this in <<_getting_a_repo>>, where we show creating a brand new repository to start working with. +We first introduce this in <>, where we show creating a brand new repository to start working with. -We talk briefly about how you can change the default branch from ``master'' in <<_remote_branches>>. +We talk briefly about how you can change the default branch from ``master'' in <>. -We use this command to create an empty bare repository for a server in <<_bare_repo>>. +We use this command to create an empty bare repository for a server in <>. -Finally, we go through some of the details of what it actually does behind the scenes in <<_plumbing_porcelain>>. +Finally, we go through some of the details of what it actually does behind the scenes in <>. ==== git clone @@ -65,13 +100,13 @@ It creates a new directory, goes into it and runs `git init` to make it an empty The `git clone` command is used in dozens of places throughout the book, but we'll just list a few interesting places. -It's basically introduced and explained in <<_git_cloning>>, where we go through a few examples. +It's basically introduced and explained in <>, where we go through a few examples. -In <<_git_on_the_server>> we look at using the `--bare` option to create a copy of a Git repository with no working directory. +In <> we look at using the `--bare` option to create a copy of a Git repository with no working directory. -In <<_bundling>> we use it to unbundle a bundled Git repository. +In <> we use it to unbundle a bundled Git repository. -Finally, in <<_cloning_submodules>> we learn the `--recursive` option to make cloning a repository with submodules a little simpler. +Finally, in <> we learn the `--recurse-submodules` option to make cloning a repository with submodules a little simpler. Though it's used in many other places through the book, these are the ones that are somewhat unique or where it is used in ways that are a little different. @@ -88,13 +123,13 @@ When the `git commit` command is run, by default it only looks at this staging a This command is an incredibly important command in Git and is mentioned or used dozens of times in this book. We'll quickly cover some of the unique uses that can be found. -We first introduce and explain `git add` in detail in <<_tracking_files>>. +We first introduce and explain `git add` in detail in <>. -We mention how to use it to resolve merge conflicts in <<_basic_merge_conflicts>>. +We mention how to use it to resolve merge conflicts in <>. -We go over using it to interactively stage only specific parts of a modified file in <<_interactive_staging>>. +We go over using it to interactively stage only specific parts of a modified file in <>. -Finally, we emulate it at a low level in <<_tree_objects>>, so you can get an idea of what it's doing behind the scenes. +Finally, we emulate it at a low level in <>, so you can get an idea of what it's doing behind the scenes. ==== git status @@ -102,7 +137,7 @@ The `git status` command will show you the different states of files in your wor Which files are modified and unstaged and which are staged but not yet committed. In its normal form, it also will show you some basic hints on how to move files between these stages. -We first cover `status` in <<_checking_status>>, both in its basic and simplified forms. +We first cover `status` in <>, both in its basic and simplified forms. While we use it throughout the book, pretty much everything you can do with the `git status` command is covered there. ==== git diff @@ -110,36 +145,36 @@ While we use it throughout the book, pretty much everything you can do with the The `git diff` command is used when you want to see differences between any two trees. This could be the difference between your working environment and your staging area (`git diff` by itself), between your staging area and your last commit (`git diff --staged`), or between two commits (`git diff master branchB`). -We first look at the basic uses of `git diff` in <<_git_diff_staged>>, where we show how to see what changes are staged and which are not yet staged. +We first look at the basic uses of `git diff` in <>, where we show how to see what changes are staged and which are not yet staged. -We use it to look for possible whitespace issues before committing with the `--check` option in <<_commit_guidelines>>. +We use it to look for possible whitespace issues before committing with the `--check` option in <>. -We see how to check the differences between branches more effectively with the `git diff A...B` syntax in <<_what_is_introduced>>. +We see how to check the differences between branches more effectively with the `git diff A...B` syntax in <>. -We use it to filter out whitespace differences with `-b` and how to compare different stages of conflicted files with `--theirs`, `--ours` and `--base` in <<_advanced_merging>>. +We use it to filter out whitespace differences with `-b` and how to compare different stages of conflicted files with `--theirs`, `--ours` and `--base` in <>. -Finally, we use it to effectively compare submodule changes with `--submodule` in <<_starting_submodules>>. +Finally, we use it to effectively compare submodule changes with `--submodule` in <>. ==== git difftool The `git difftool` command simply launches an external tool to show you the difference between two trees in case you want to use something other than the built in `git diff` command. -We only briefly mention this in <<_git_diff_staged>>. +We only briefly mention this in <>. ==== git commit The `git commit` command takes all the file contents that have been staged with `git add` and records a new permanent snapshot in the database and then moves the branch pointer on the current branch up to it. -We first cover the basics of committing in <<_committing_changes>>. +We first cover the basics of committing in <>. There we also demonstrate how to use the `-a` flag to skip the `git add` step in daily workflows and how to use the `-m` flag to pass a commit message in on the command line instead of firing up an editor. -In <<_undoing>> we cover using the `--amend` option to redo the most recent commit. +In <> we cover using the `--amend` option to redo the most recent commit. -In <<_git_branches_overview>>, we go into much more detail about what `git commit` does and why it does it like that. +In <>, we go into much more detail about what `git commit` does and why it does it like that. -We looked at how to sign commits cryptographically with the `-S` flag in <<_signing_commits>>. +We looked at how to sign commits cryptographically with the `-S` flag in <>. -Finally, we take a look at what the `git commit` command does in the background and how it's actually implemented in <<_git_commit_objects>>. +Finally, we take a look at what the `git commit` command does in the background and how it's actually implemented in <>. ==== git reset @@ -147,34 +182,34 @@ The `git reset` command is primarily used to undo things, as you can possibly te It moves around the `HEAD` pointer and optionally changes the `index` or staging area and can also optionally change the working directory if you use `--hard`. This final option makes it possible for this command to lose your work if used incorrectly, so make sure you understand it before using it. -We first effectively cover the simplest use of `git reset` in <<_unstaging>>, where we use it to unstage a file we had run `git add` on. +We first effectively cover the simplest use of `git reset` in <>, where we use it to unstage a file we had run `git add` on. -We then cover it in quite some detail in <<_git_reset>>, which is entirely devoted to explaining this command. +We then cover it in quite some detail in <>, which is entirely devoted to explaining this command. -We use `git reset --hard` to abort a merge in <<_abort_merge>>, where we also use `git merge --abort`, which is a bit of a wrapper for the `git reset` command. +We use `git reset --hard` to abort a merge in <>, where we also use `git merge --abort`, which is a bit of a wrapper for the `git reset` command. ==== git rm The `git rm` command is used to remove files from the staging area and working directory for Git. It is similar to `git add` in that it stages a removal of a file for the next commit. -We cover the `git rm` command in some detail in <<_removing_files>>, including recursively removing files and only removing files from the staging area but leaving them in the working directory with `--cached`. +We cover the `git rm` command in some detail in <>, including recursively removing files and only removing files from the staging area but leaving them in the working directory with `--cached`. -The only other differing use of `git rm` in the book is in <<_removing_objects>> where we briefly use and explain the `--ignore-unmatch` when running `git filter-branch`, which simply makes it not error out when the file we are trying to remove doesn't exist. +The only other differing use of `git rm` in the book is in <> where we briefly use and explain the `--ignore-unmatch` when running `git filter-branch`, which simply makes it not error out when the file we are trying to remove doesn't exist. This can be useful for scripting purposes. ==== git mv The `git mv` command is a thin convenience command to move a file and then run `git add` on the new file and `git rm` on the old file. -We only briefly mention this command in <<_git_mv>>. +We only briefly mention this command in <>. ==== git clean The `git clean` command is used to remove unwanted files from your working directory. This could include removing temporary build artifacts or merge conflict files. -We cover many of the options and scenarios in which you might used the clean command in <<_git_clean>>. +We cover many of the options and scenarios in which you might used the clean command in <>. === Branching and Merging @@ -185,48 +220,48 @@ There are just a handful of commands that implement most of the branching and me The `git branch` command is actually something of a branch management tool. It can list the branches you have, create a new branch, delete branches and rename branches. -Most of <<_git_branching>> is dedicated to the `branch` command and it's used throughout the entire chapter. -We first introduce it in <<_create_new_branch>> and we go through most of its other features (listing and deleting) in <<_branch_management>>. +Most of <> is dedicated to the `branch` command and it's used throughout the entire chapter. +We first introduce it in <> and we go through most of its other features (listing and deleting) in <>. -In <<_tracking_branches>> we use the `git branch -u` option to set up a tracking branch. +In <> we use the `git branch -u` option to set up a tracking branch. -Finally, we go through some of what it does in the background in <<_git_refs>>. +Finally, we go through some of what it does in the background in <>. ==== git checkout The `git checkout` command is used to switch branches and check content out into your working directory. -We first encounter the command in <<_switching_branches>> along with the `git branch` command. +We first encounter the command in <> along with the `git branch` command. -We see how to use it to start tracking branches with the `--track` flag in <<_tracking_branches>>. +We see how to use it to start tracking branches with the `--track` flag in <>. -We use it to reintroduce file conflicts with `--conflict=diff3` in <<_checking_out_conflicts>>. +We use it to reintroduce file conflicts with `--conflict=diff3` in <>. -We go into closer detail on its relationship with `git reset` in <<_git_reset>>. +We go into closer detail on its relationship with `git reset` in <>. -Finally, we go into some implementation detail in <<_the_head>>. +Finally, we go into some implementation detail in <>. ==== git merge The `git merge` tool is used to merge one or more branches into the branch you have checked out. It will then advance the current branch to the result of the merge. -The `git merge` command was first introduced in <<_basic_branching>>. +The `git merge` command was first introduced in <>. Though it is used in various places in the book, there are very few variations of the `merge` command -- generally just `git merge ` with the name of the single branch you want to merge in. -We covered how to do a squashed merge (where Git merges the work but pretends like it's just a new commit without recording the history of the branch you're merging in) at the very end of <<_public_project>>. +We covered how to do a squashed merge (where Git merges the work but pretends like it's just a new commit without recording the history of the branch you're merging in) at the very end of <>. -We went over a lot about the merge process and command, including the `-Xignore-space-change` command and the `--abort` flag to abort a problem merge in <<_advanced_merging>>. +We went over a lot about the merge process and command, including the `-Xignore-space-change` command and the `--abort` flag to abort a problem merge in <>. -We learned how to verify signatures before merging if your project is using GPG signing in <<_signing_commits>>. +We learned how to verify signatures before merging if your project is using GPG signing in <>. -Finally, we learned about Subtree merging in <<_subtree_merge>>. +Finally, we learned about Subtree merging in <>. ==== git mergetool The `git mergetool` command simply launches an external merge helper in case you have issues with a merge in Git. -We mention it quickly in <<_basic_merge_conflicts>> and go into detail on how to implement your own external merge tool in <<_external_merge_tools>>. +We mention it quickly in <> and go into detail on how to implement your own external merge tool in <>. ==== git log @@ -236,37 +271,37 @@ It is also often used to show differences between two or more branches at the co This command is used in nearly every chapter of the book to demonstrate the history of a project. -We introduce the command and cover it in some depth in <<_viewing_history>>. +We introduce the command and cover it in some depth in <>. There we look at the `-p` and `--stat` option to get an idea of what was introduced in each commit and the `--pretty` and `--oneline` options to view the history more concisely, along with some simple date and author filtering options. -In <<_create_new_branch>> we use it with the `--decorate` option to easily visualize where our branch pointers are located and we also use the `--graph` option to see what divergent histories look like. +In <> we use it with the `--decorate` option to easily visualize where our branch pointers are located and we also use the `--graph` option to see what divergent histories look like. -In <<_private_team>> and <<_commit_ranges>> we cover the `branchA..branchB` syntax to use the `git log` command to see what commits are unique to a branch relative to another branch. -In <<_commit_ranges>> we go through this fairly extensively. +In <> and <> we cover the `branchA..branchB` syntax to use the `git log` command to see what commits are unique to a branch relative to another branch. +In <> we go through this fairly extensively. -In <<_merge_log>> and <<_triple_dot>> we cover using the `branchA...branchB` format and the `--left-right` syntax to see what is in one branch or the other but not in both. -In <<_merge_log>> we also look at how to use the `--merge` option to help with merge conflict debugging as well as using the `--cc` option to look at merge commit conflicts in your history. +In <> and <> we cover using the `branchA...branchB` format and the `--left-right` syntax to see what is in one branch or the other but not in both. +In <> we also look at how to use the `--merge` option to help with merge conflict debugging as well as using the `--cc` option to look at merge commit conflicts in your history. -In <<_git_reflog>> we use the `-g` option to view the Git reflog through this tool instead of doing branch traversal. +In <> we use the `-g` option to view the Git reflog through this tool instead of doing branch traversal. -In <<_searching>> we look at using the `-S` and `-L` options to do fairly sophisticated searches for something that happened historically in the code such as seeing the history of a function. +In <> we look at using the `-S` and `-L` options to do fairly sophisticated searches for something that happened historically in the code such as seeing the history of a function. -In <<_signing_commits>> we see how to use `--show-signature` to add a validation string to each commit in the `git log` output based on if it was validly signed or not. +In <> we see how to use `--show-signature` to add a validation string to each commit in the `git log` output based on if it was validly signed or not. ==== git stash The `git stash` command is used to temporarily store uncommitted work in order to clean out your working directory without having to commit unfinished work on a branch. -This is basically entirely covered in <<_git_stashing>>. +This is basically entirely covered in <>. ==== git tag The `git tag` command is used to give a permanent bookmark to a specific point in the code history. Generally this is used for things like releases. -This command is introduced and covered in detail in <<_git_tagging>> and we use it in practice in <<_tagging_releases>>. +This command is introduced and covered in detail in <> and we use it in practice in <>. -We also cover how to create a GPG signed tag with the `-s` flag and verify one with the `-v` flag in <<_signing>>. +We also cover how to create a GPG signed tag with the `-s` flag and verify one with the `-v` flag in <>. === Sharing and Updating Projects @@ -278,45 +313,45 @@ When you are ready to share your work or pull changes from elsewhere, there are The `git fetch` command communicates with a remote repository and fetches down all the information that is in that repository that is not in your current one and stores it in your local database. -We first look at this command in <<_fetching_and_pulling>> and we continue to see examples of it use in <<_remote_branches>>. +We first look at this command in <> and we continue to see examples of its use in <>. -We also use it in several of the examples in <<_contributing_project>>. +We also use it in several of the examples in <>. -We use it to fetch a single specific reference that is outside of the default space in <<_pr_refs>> and we see how to fetch from a bundle in <<_bundling>>. +We use it to fetch a single specific reference that is outside of the default space in <> and we see how to fetch from a bundle in <>. -We set up highly custom refspecs in order to make `git fetch` do something a little different than the default in <<_refspec>>. +We set up highly custom refspecs in order to make `git fetch` do something a little different than the default in <>. ==== git pull The `git pull` command is basically a combination of the `git fetch` and `git merge` commands, where Git will fetch from the remote you specify and then immediately try to merge it into the branch you're on. -We introduce it quickly in <<_fetching_and_pulling>> and show how to see what it will merge if you run it in <<_inspecting_remote>>. +We introduce it quickly in <> and show how to see what it will merge if you run it in <>. -We also see how to use it to help with rebasing difficulties in <<_rebase_rebase>>. +We also see how to use it to help with rebasing difficulties in <>. -We show how to use it with a URL to pull in changes in a one-off fashion in <<_checking_out_remotes>>. +We show how to use it with a URL to pull in changes in a one-off fashion in <>. -Finally, we very quickly mention that you can use the `--verify-signatures` option to it in order to verify that commits you are pulling have been GPG signed in <<_signing_commits>>. +Finally, we very quickly mention that you can use the `--verify-signatures` option to it in order to verify that commits you are pulling have been GPG signed in <>. ==== git push The `git push` command is used to communicate with another repository, calculate what your local database has that the remote one does not, and then pushes the difference into the other repository. It requires write access to the other repository and so normally is authenticated somehow. -We first look at the `git push` command in <<_pushing_remotes>>. +We first look at the `git push` command in <>. Here we cover the basics of pushing a branch to a remote repository. -In <<_pushing_branches>> we go a little deeper into pushing specific branches and in <<_tracking_branches>> we see how to set up tracking branches to automatically push to. -In <<_delete_branches>> we use the `--delete` flag to delete a branch on the server with `git push`. +In <> we go a little deeper into pushing specific branches and in <> we see how to set up tracking branches to automatically push to. +In <> we use the `--delete` flag to delete a branch on the server with `git push`. -Throughout <<_contributing_project>> we see several examples of using `git push` to share work on branches through multiple remotes. +Throughout <> we see several examples of using `git push` to share work on branches through multiple remotes. -We see how to use it to share tags that you have made with the `--tags` option in <<_sharing_tags>>. +We see how to use it to share tags that you have made with the `--tags` option in <>. -In <<_publishing_submodules>> we use the `--recurse-submodules` option to check that all of our submodules work has been published before pushing the superproject, which can be really helpful when using submodules. +In <> we use the `--recurse-submodules` option to check that all of our submodules work has been published before pushing the superproject, which can be really helpful when using submodules. -In <<_other_client_hooks>> we talk briefly about the `pre-push` hook, which is a script we can setup to run before a push completes to verify that it should be allowed to push. +In <> we talk briefly about the `pre-push` hook, which is a script we can setup to run before a push completes to verify that it should be allowed to push. -Finally, in <<_pushing_refspecs>> we look at pushing with a full refspec instead of the general shortcuts that are normally used. +Finally, in <> we look at pushing with a full refspec instead of the general shortcuts that are normally used. This can help you be very specific about what work you wish to share. ==== git remote @@ -325,7 +360,7 @@ The `git remote` command is a management tool for your record of remote reposito It allows you to save long URLs as short handles, such as ``origin'' so you don't have to type them out all the time. You can have several of these and the `git remote` command is used to add, change and delete them. -This command is covered in detail in <<_remote_repos>>, including listing, adding, removing and renaming them. +This command is covered in detail in <>, including listing, adding, removing and renaming them. It is used in nearly every subsequent chapter in the book too, but always in the standard `git remote add ` format. @@ -333,7 +368,7 @@ It is used in nearly every subsequent chapter in the book too, but always in the The `git archive` command is used to create an archive file of a specific snapshot of the project. -We use `git archive` to create a tarball of a project for sharing in <<_preparing_release>>. +We use `git archive` to create a tarball of a project for sharing in <>. ==== git submodule @@ -341,7 +376,7 @@ The `git submodule` command is used to manage external repositories within a nor This could be for libraries or other types of shared resources. The `submodule` command has several sub-commands (`add`, `update`, `sync`, etc) for managing these resources. -This command is only mentioned and entirely covered in <<_git_submodules>>. +This command is only mentioned and entirely covered in <>. === Inspection and Comparison @@ -350,25 +385,25 @@ This command is only mentioned and entirely covered in <<_git_submodules>>. The `git show` command can show a Git object in a simple and human readable way. Normally you would use this to show the information about a tag or a commit. -We first use it to show annotated tag information in <<_annotated_tags>>. +We first use it to show annotated tag information in <>. -Later we use it quite a bit in <<_revision_selection>> to show the commits that our various revision selections resolve to. +Later we use it quite a bit in <> to show the commits that our various revision selections resolve to. -One of the more interesting things we do with `git show` is in <<_manual_remerge>> to extract specific file contents of various stages during a merge conflict. +One of the more interesting things we do with `git show` is in <> to extract specific file contents of various stages during a merge conflict. ==== git shortlog The `git shortlog` command is used to summarize the output of `git log`. It will take many of the same options that the `git log` command will but instead of listing out all of the commits it will present a summary of the commits grouped by author. -We showed how to use it to create a nice changelog in <<_the_shortlog>>. +We showed how to use it to create a nice changelog in <>. ==== git describe The `git describe` command is used to take anything that resolves to a commit and produces a string that is somewhat human-readable and will not change. It's a way to get a description of a commit that is as unambiguous as a commit SHA-1 but more understandable. -We use `git describe` in <<_build_number>> and <<_preparing_release>> to get a string to name our release file after. +We use `git describe` in <> and <> to get a string to name our release file after. === Debugging @@ -380,20 +415,20 @@ This ranges from figuring out where something was introduced to figuring out who The `git bisect` tool is an incredibly helpful debugging tool used to find which specific commit was the first one to introduce a bug or problem by doing an automatic binary search. -It is fully covered in <<_binary_search>> and is only mentioned in that section. +It is fully covered in <> and is only mentioned in that section. ==== git blame The `git blame` command annotates the lines of any file with which commit was the last one to introduce a change to each line of the file and what person authored that commit. This is helpful in order to find the person to ask for more information about a specific section of your code. -It is covered in <<_file_annotation>> and is only mentioned in that section. +It is covered in <> and is only mentioned in that section. ==== git grep The `git grep` command can help you find any string or regular expression in any of the files in your source code, even older versions of your project. -It is covered in <<_git_grep>> and is only mentioned in that section. +It is covered in <> and is only mentioned in that section. === Patching @@ -405,27 +440,27 @@ These commands help you manage your branches in this manner. The `git cherry-pick` command is used to take the change introduced in a single Git commit and try to re-introduce it as a new commit on the branch you're currently on. This can be useful to only take one or two commits from a branch individually rather than merging in the branch which takes all the changes. -Cherry picking is described and demonstrated in <<_rebase_cherry_pick>>. +Cherry picking is described and demonstrated in <>. ==== git rebase The `git rebase` command is basically an automated `cherry-pick`. It determines a series of commits and then cherry-picks them one by one in the same order somewhere else. -Rebasing is covered in detail in <<_rebasing>>, including covering the collaborative issues involved with rebasing branches that are already public. +Rebasing is covered in detail in <>, including covering the collaborative issues involved with rebasing branches that are already public. -We use it in practice during an example of splitting your history into two separate repositories in <<_replace>>, using the `--onto` flag as well. +We use it in practice during an example of splitting your history into two separate repositories in <>, using the `--onto` flag as well. -We go through running into a merge conflict during rebasing in <<_rerere>>. +We go through running into a merge conflict during rebasing in <>. -We also use it in an interactive scripting mode with the `-i` option in <<_changing_multiple>>. +We also use it in an interactive scripting mode with the `-i` option in <>. ==== git revert The `git revert` command is essentially a reverse `git cherry-pick`. It creates a new commit that applies the exact opposite of the change introduced in the commit you're targeting, essentially undoing or reverting it. -We use this in <<_reverse_commit>> to undo a merge commit. +We use this in <> to undo a merge commit. === Email @@ -437,43 +472,43 @@ Git has a number of tools built into it that help make this process easier, from The `git apply` command applies a patch created with the `git diff` or even GNU diff command. It is similar to what the `patch` command might do with a few small differences. -We demonstrate using it and the circumstances in which you might do so in <<_patches_from_email>>. +We demonstrate using it and the circumstances in which you might do so in <>. ==== git am The `git am` command is used to apply patches from an email inbox, specifically one that is mbox formatted. This is useful for receiving patches over email and applying them to your project easily. -We covered usage and workflow around `git am` in <<_git_am>> including using the `--resolved`, `-i` and `-3` options. +We covered usage and workflow around `git am` in <> including using the `--resolved`, `-i` and `-3` options. -There are also a number of hooks you can use to help with the workflow around `git am` and they are all covered in <<_email_hooks>>. +There are also a number of hooks you can use to help with the workflow around `git am` and they are all covered in <>. -We also use it to apply patch formatted GitHub Pull Request changes in <<_email_notifications>>. +We also use it to apply patch formatted GitHub Pull Request changes in <>. ==== git format-patch The `git format-patch` command is used to generate a series of patches in mbox format that you can use to send to a mailing list properly formatted. -We go through an example of contributing to a project using the `git format-patch` tool in <<_project_over_email>>. +We go through an example of contributing to a project using the `git format-patch` tool in <>. ==== git imap-send The `git imap-send` command uploads a mailbox generated with `git format-patch` into an IMAP drafts folder. -We go through an example of contributing to a project by sending patches with the `git imap-send` tool in <<_project_over_email>>. +We go through an example of contributing to a project by sending patches with the `git imap-send` tool in <>. ==== git send-email The `git send-email` command is used to send patches that are generated with `git format-patch` over email. -We go through an example of contributing to a project by sending patches with the `git send-email` tool in <<_project_over_email>>. +We go through an example of contributing to a project by sending patches with the `git send-email` tool in <>. ==== git request-pull The `git request-pull` command is simply used to generate an example message body to email to someone. If you have a branch on a public server and want to let someone know how to integrate those changes without sending the patches over email, you can run this command and send the output to the person you want to pull the changes in. -We demonstrate how to use `git request-pull` to generate a pull message in <<_public_project>>. +We demonstrate how to use `git request-pull` to generate a pull message in <>. === External Systems @@ -484,13 +519,13 @@ Git comes with a few commands to integrate with other version control systems. The `git svn` command is used to communicate with the Subversion version control system as a client. This means you can use Git to checkout from and commit to a Subversion server. -This command is covered in depth in <<_git_svn>>. +This command is covered in depth in <>. ==== git fast-import For other version control systems or importing from nearly any format, you can use `git fast-import` to quickly map the other format to something Git can easily record. -This command is covered in depth in <<_custom_importer>>. +This command is covered in depth in <>. === Administration @@ -501,40 +536,40 @@ If you're administering a Git repository or need to fix something in a big way, The `git gc` command runs ``garbage collection'' on your repository, removing unnecessary files in your database and packing up the remaining files into a more efficient format. This command normally runs in the background for you, though you can manually run it if you wish. -We go over some examples of this in <<_git_gc>>. +We go over some examples of this in <>. ==== git fsck The `git fsck` command is used to check the internal database for problems or inconsistencies. -We only quickly use this once in <<_data_recovery>> to search for dangling objects. +We only quickly use this once in <> to search for dangling objects. ==== git reflog The `git reflog` command goes through a log of where all the heads of your branches have been as you work to find commits you may have lost through rewriting histories. -We cover this command mainly in <<_git_reflog>>, where we show normal usage to and how to use `git log -g` to view the same information with `git log` output. +We cover this command mainly in <>, where we show normal usage to and how to use `git log -g` to view the same information with `git log` output. -We also go through a practical example of recovering such a lost branch in <<_data_recovery>>. +We also go through a practical example of recovering such a lost branch in <>. ==== git filter-branch The `git filter-branch` command is used to rewrite loads of commits according to certain patterns, like removing a file everywhere or filtering the entire repository down to a single subdirectory for extracting a project. -In <<_removing_file_every_commit>> we explain the command and explore several different options such as `--commit-filter`, `--subdirectory-filter` and `--tree-filter`. +In <> we explain the command and explore several different options such as `--commit-filter`, `--subdirectory-filter` and `--tree-filter`. -In <<_git_p4>> and <<_git_tfs>> we use it to fix up imported external repositories. +In <> and <> we use it to fix up imported external repositories. === Plumbing Commands There were also quite a number of lower level plumbing commands that we encountered in the book. -The first one we encounter is `ls-remote` in <<_pr_refs>> which we use to look at the raw references on the server. +The first one we encounter is `ls-remote` in <> which we use to look at the raw references on the server. -We use `ls-files` in <<_manual_remerge>>, <<_rerere>> and <<_the_index>> to take a more raw look at what your staging area looks like. +We use `ls-files` in <>, <> and <> to take a more raw look at what your staging area looks like. -We also mention `rev-parse` in <<_branch_references>> to take just about any string and turn it into an object SHA-1. +We also mention `rev-parse` in <> to take just about any string and turn it into an object SHA-1. -However, most of the low level plumbing commands we cover are in <<_git_internals>>, which is more or less what the chapter is focused on. +However, most of the low level plumbing commands we cover are in <>, which is more or less what the chapter is focused on. We tried to avoid use of them throughout most of the rest of the book. diff --git a/CONTRIBUTING.asc b/CONTRIBUTING.asc index f72934f6e..acc0ab0a5 100644 --- a/CONTRIBUTING.asc +++ b/CONTRIBUTING.asc @@ -1,15 +1,44 @@ = Zur Übersetzung der zweiten Auflage von Git Pro beitragen +== Lizenz + +Mit Erzeugen eines Pull-Requests für dieses Repository stimmen Sie zu, dass Ihre Arbeit unter die angegebene link:LICENSE.asc[Projektlizenz] gestellt wird. +Außerdem erklären Sie sich damit einverstanden, eine solche Lizenz an Ihrer Arbeit den Hauptautoren @ben und @schacon zu gewähren, die sie für zukünftige, gedruckte Ausgaben benötigen. +Sollten Ihre Änderungen in einer gedruckten Fassung erscheinen, so werden Sie in die Liste der link:book/contributors.asc[Mitwirkenden] aufgenommen. + == Ein Problem melden Bevor Sie ein Problem melden, bitten wir Sie zu überprüfen, ob sich nicht ein ähnliches oder gar dasselbe Problem bereits im Bugtracking-System befindet. Wenn das Problem auch auf der link:https://git-scm.com[Git-Website] zu finden ist, überprüfen Sie bitte auch, ob das Problem dort noch aktuell ist. Es könnte schon erledigt, aber noch nicht veröffentlicht sein. -== Lizenz +== Kleinere Korrekturen + +Fehlerkorrekturen und grundlegende Klarstellungen werden akzeptiert, wenn wir uns einig sind, dass sie den Inhalt verbessern. +Sie können auch ein Issue eröffnen, damit wir herausfinden können, wie oder ob es gelöst werden muss. + +Wenn Sie dies noch nie zuvor getan haben, kann der link:https://guides.github.com/introduction/flow/[Flow Guide] hilfreich sein. + +== Größere Änderungen + +Öffnen Sie ein Issue zur Diskussion, bevor Sie beginnen. +Diese Veränderungen sind in der Regel sehr subjektiv, oft nur klärende Dinge für einen kleinen Prozentsatz der Menschen und es lohnt sich selten, sie zu akzeptieren. +Professionelle Textredakteure haben diesen Inhalt bereits mehrmals überprüft, so dass es unwahrscheinlich ist, dass Ihre Texte so viel besser werden, dass es sich lohnt, große Textmengen zu ändern, obwohl Sie vielleicht einen etwas besseren Geschmack und bessere Grammatik haben als wir. + +== Abbildungen + +Die Bilder in diesem Buch wurden mit link:https://www.sketchapp.com/[Sketch 3] und der link:https://github.com/progit/progit2/blob/master/diagram-source/progit.sketch[mitgelieferten Sketchbook-Datei] erstellt. + +Um eine Abbildung einzufügen: + +1. Fügen Sie eine Seite zum Sketchbook hinzu. Versuchen Sie möglichst die enthaltenen Symbole zu verwenden. +2. Fügen Sie Ihrer Seite ein „Slice“ hinzu. Geben Sie ihm einen Namen, der mit dem PNG-Dateinamen des Ziels übereinstimmt, relativ zur Root des Quellverzeichnisses. +3. Vergewissern Sie sich, dass Ihr Slice so eingestellt ist, dass er mit „800w“ exportiert wird. + +== Übersetzungen -Mit Erzeugen eines Pull-Requests für dieses Repository stimmen Sie zu, dass Ihre Arbeit unter die angegebene link:LICENSE.asc[Projektlizenz] gestellt wird. Sollten Ihre Änderungen in einer gedruckten Fassung erscheinen, so werden Sie in die Liste der link:book/contributors.asc[Mitwirkenden] aufgenommen. +Wenn Sie einen Beitrag zur Übersetzung von Pro Git in Ihre Sprache leisten möchten, werfen Sie einen Blick auf link:https://github.com/progit/progit2/blob/master/TRANSLATING.md[TRANSLATING.md]. == Weiterführende Hinweise zur deutschen Übersetzung -Alle weiterführenden Hinweise zur deutschen Übersetzung finden sie im Dokument link:TRANSLATION_NOTES.asc[Hinweise zur deutschen Übersetzung]. +Alle weiterführenden Hinweise zur deutschen Übersetzung finden sie im Dokument link:TRANSLATION_NOTES_DE.asc[Hinweise zur deutschen Übersetzung]. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..c977233c2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contributing to Pro Git (2nd Edition) + +## Licensing + +By opening a pull request to this repository, you agree to provide your work under the [project license](LICENSE.asc). +Also, you agree to grant such license of your work as is required for the purposes of future print editions to @ben and @schacon. +Should your changes appear in a printed edition, you'll be included in the [contributors list](book/contributors.asc). + +## Signaling an Issue + +Before signaling an issue, please check that there isn't already a similar one in the bug tracking system. + +Also, if this issue has been spotted on the git-scm.com site, please cross-check that it is still present in the pdf version. +The issue may have already been corrected, but the changes have not been deployed yet. + +## Small Corrections + +Errata and basic clarifications will be accepted if we agree that they improve the content. +You can also open an issue so we can figure out how or if it needs to be addressed. + +If you've never done this before, the [flow guide](https://guides.github.com/introduction/flow/) might be useful. + +## Large Rewrites + +Open an issue for discussion before you start. +These changes tend to be very subjective, often only clarifying things for some small percentage of people and it's rarely worth the time to accept them. +Professional copy editors have already reviewed this content multiple times so while you may have somewhat better taste and grammar than we do it's unlikely that your prose is going to be *so* much better that it's worth changing vast swaths of text. + +## Figures + +The images in this book were generated using [Sketch 3](https://www.sketchapp.com/), with the [included sketchbook file](diagram-source/progit.sketch). + +To add a figure: + +1. Add a page to the sketchbook. +Try to use the included symbols wherever possible. +2. Add a "slice" to your page. +Give it a name that matches the destination PNG filename, relative from the root of the source directory. +3. Make sure your slice is set to export at "800w". + + +## Translations + +If you would like to contribute to translating Pro Git into your language, take a look at [TRANSLATING.md](TRANSLATING.md). diff --git a/Gemfile b/Gemfile index d7bd91223..4ecffb4fd 100644 --- a/Gemfile +++ b/Gemfile @@ -1,13 +1,13 @@ source 'https://rubygems.org' gem 'rake' -gem 'asciidoctor', '1.5.0' +gem 'asciidoctor', '1.5.6.1' gem 'json' gem 'awesome_print' -gem 'asciidoctor-epub3', '1.0.0.alpha.2' -gem 'asciidoctor-pdf', '1.5.0.alpha.5' +gem 'asciidoctor-epub3', :git => 'https://github.com/asciidoctor/asciidoctor-epub3' +gem 'asciidoctor-pdf', '1.5.0.alpha.16' gem 'coderay' gem 'pygments.rb' diff --git a/LICENSE.asc b/LICENSE.asc index 81f2824e2..be3737abf 100644 --- a/LICENSE.asc +++ b/LICENSE.asc @@ -1 +1,2 @@ -This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. +Dieses Werk ist lizensiert unter der „Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported“ Lizenz. +Um eine Kopie dieser Lizenz zu lesen, besuchen Sie https://creativecommons.org/licenses/by-nc-sa/3.0 oder senden Sie einen Brief an Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. diff --git a/README.asc b/README.asc index a9bf918f7..878d78cb4 100644 --- a/README.asc +++ b/README.asc @@ -1,22 +1,21 @@ = Pro Git: Zweite Auflage -Herzlich willkommen bei der zweiten Auflage des Buchs Pro Git. +Herzlich willkommen bei der zweiten Auflage des Buchs „Pro Git“. -Sie finden dieses Buch in Zukunft online unter: https://git-scm.com/book/de/v2 +Sie finden dieses Buch online unter: https://git-scm.com/book/de/v2 -Wie die erste, ist auch die zweite Auflage von Pro Git Open Source und steht unter der Creative Commons-Lizenz. +Wie die erste, ist auch die zweite Auflage von *Pro Git* Open Source und steht unter der Creative Commons-Lizenz. -Im Vergleich zur ersten Auflage haben sich in der zweiten Auflage allerdings ein paar Dinge geändert: Zum einen wird jetzt statt Markdown das AsciiDoc-Format verwendet und zum anderen wird O’Reilly-Buildserver unter der link:https://atlas.oreilly.com[Atlas Platform] genutzt. Mit Hilfe von Continuous Integration wird das Buch in allen Sprachen erstellt und zur Verfügung gestellt. +Im Vergleich zur ersten Auflage haben sich in der zweiten Auflage allerdings ein paar Dinge geändert: +Unter anderem haben wir von Markdown auf das fantastische Asciidoc-Format für den Text des Buches umgestellt. -Statt eines großen Repositorys für alle Sprachen wird jede Sprache mittlerweile in einem eigenen Repository verwaltet. Im Dokument link:TRANSLATION_NOTES.asc[Hilfe bei der deutschen Übersetzung] finden Sie weitere Informationen. +Statt eines großen Repositorys für alle Sprachen wird jede Sprache mittlerweile in einem eigenen Repository verwaltet. +In den Dokumenten link:TRANSLATING.md[Pro Git Übersetzung] und link:TRANSLATION_NOTES_DE.asc[Hinweise zur deutschen Übersetzung] finden Sie weitere Informationen. == Wie kann das Buch erstellt werden? -Es gibt zwei Möglichkeiten, um aus dem Quellcode eine E-Book-Version des Buchs zu erstellen. - -Die einfachste Möglichkeit besteht für Sie darin, uns das Erstellen zu überlassen. Mit Hilfe von Continuous Integration wird der Master-Branch ständig überwacht und automatisch eine neue Version erstellt, wenn sich dieser ändert. Aktuelle Builds finden Sie link:https://git-scm.com/book/de/v2[hier]. - -Wenn Sie das Buch lieber manuell erzeugen möchten, können Sie dazu link:https://asciidoctor.org[Asciidoctor] nutzen. Verwenden Sie dazu die folgenden Befehle, um das Buch in den Formaten HTML, EPUB, MOBI und PDF zu erstellen: +Sie können die E-Book-Dateien manuell mit Asciidoctor erzeugen. +Wenn Sie die folgenden Befehle ausführen, können Sie auch HTML-, Epub-, Mobi- und PDF-Ausgabedateien erhalten: ---- $ bundle install @@ -28,17 +27,16 @@ Converting to EPub... Converting to Mobi (kf8)... -- Mobi output at progit.mobi Converting to PDF... - -- PDF output at progit.pdf + -- PDF output at progit.pdf ---- -Zum Konvertieren werden die Projekte `asciidoctor`, `asciidoctor-pdf` und `asciidoctor-epub` genutzt. - == Ein Problem melden Bevor Sie ein Problem melden, bitten wir Sie zu überprüfen, ob sich nicht ein ähnliches oder gar dasselbe Problem bereits im Bugtracking-System befindet. -Wenn das Problem auch auf der link:https://git-scm.com[Git-Website] zu finden ist, überprüfen Sie bitte auch, ob das Problem dort noch aktuell ist. Es könnte schon erledigt, aber noch nicht veröffentlicht sein. +Wenn Sie dieses Problem auf der Website git-scm.com entdeckt haben, überprüfen Sie bitte nochmals, ob es in diesem Repo noch vorhanden ist. +Das Problem wurde eventuell schon behoben, aber die Änderungen noch nicht eingespielt. == Mithelfen -Wenn Sie uns bei der deutschen Übersetzung helfen wollen, sei es um einen Text neu zu übersetzen oder einen Rechtschreibfehler zu verbessern, finden Sie im Dokument link:TRANSLATION_NOTES.asc[Hilfe bei der deutschen Übersetzung] weitere Informationen. +Wenn Sie uns bei der Übersetzung helfen wollen, sei es um einen Text neu zu übersetzen oder einen Rechtschreibfehler zu verbessern, finden Sie in dem Dokument link:CONTRIBUTING.asc[Contributor Guide] weitere Informationen. diff --git a/Rakefile b/Rakefile index 602386729..5b5702aaa 100644 --- a/Rakefile +++ b/Rakefile @@ -1,29 +1,34 @@ namespace :book do - desc 'prepare build' - task :prebuild do - Dir.mkdir 'images' unless Dir.exists? 'images' - Dir.glob("book/*/images/*").each do |image| - FileUtils.copy(image, "images/" + File.basename(image)) - end - end - desc 'build basic book formats' - task :build => :prebuild do - puts "Converting to HTML..." - `bundle exec asciidoctor progit.asc` - puts " -- HTML output at progit.html" + task :build do + + begin + version_string = ENV['TRAVIS_TAG'] || `git describe --tags`.chomp + if version_string.empty? + version_string = '0' + end + date_string = Time.now.strftime("%Y-%m-%d") + params = "--attribute revnumber='#{version_string}' --attribute revdate='#{date_string}'" + puts "Generating contributors list" + `git shortlog -s | grep -v -E "(Straub|Chacon)" | cut -f 2- | column -c 120 > book/contributors.txt` - puts "Converting to EPub..." - `bundle exec asciidoctor-epub3 progit.asc` - puts " -- Epub output at progit.epub" + puts "Converting to HTML..." + `bundle exec asciidoctor #{params} progit.asc` + puts " -- HTML output at progit.html" - puts "Converting to Mobi (kf8)..." - `bundle exec asciidoctor-epub3 -a ebook-format=kf8 progit.asc` - puts " -- Mobi output at progit.mobi" + puts "Converting to EPub..." + `bundle exec asciidoctor-epub3 #{params} progit.asc` + puts " -- Epub output at progit.epub" - puts "Converting to PDF... (this one takes a while)" - `bundle exec asciidoctor-pdf progit.asc 2>/dev/null` - puts " -- PDF output at progit.pdf" + puts "Converting to Mobi (kf8)..." + `bundle exec asciidoctor-epub3 #{params} -a ebook-format=kf8 progit.asc` + puts " -- Mobi output at progit.mobi" + + puts "Converting to PDF... (this one takes a while)" + `bundle exec asciidoctor-pdf #{params} progit.asc 2>/dev/null` + puts " -- PDF output at progit.pdf" + + end end end diff --git a/Special_Characters.asc b/Special_Characters.asc new file mode 100644 index 000000000..79dd0f235 --- /dev/null +++ b/Special_Characters.asc @@ -0,0 +1,84 @@ +== Sonderzeichen + +Die Tabelle ist noch in Arbeit (vorläufiger Inhalt). + +Der Inhalt dieser Datei soll auch im Wiki zu sehen sein. + +Die Eingabe von Sonderzeichen mit der normalen Standard-Tastatur ist je nach Betriebssystem und, bei Linux auch je nach Distribution/WM-Manager verschieden und kann unterschiedlich kompliziert sein. + +Das Ziel dieser Datei ist es, für die häufigsten Sonderzeichen ein `copy + paste` zu ermöglichen. + +Falls für ein notwendiges Sonderzeichen in der folgenden Tabelle kein Eintrag vorhanden ist, sollten Sie entweder selbst einen Vorschlag machen oder über „New Issue“ eine Nachricht hinterlassen. + +[TIP] +==== +Bei den Windows und macOS Shortcuts werden die Zusatztasten (strg, alt, shift) gehalten und dann der Code bzw. Zweittaste eingegeben. + +Die Ziffern in den Windows Shortcuts *müssen* über den Nummernblock eingegeben werden. +==== + +.Sonderzeichen +[cols="1,2,2,2,2,2,5", options="header"] +|=== +|Sonderzeichen |Name (de/en) |UTF-Code (hex) |HTML-Entity |Windows Shortcut |macOS Shortcut |Bemerkung +|– +|Bindestrich, Halbgeviert-Strich + +/ hyphen +|U+2013 +|\– +|`alt (+) 0150` +|`alt (+) -` +|ersetzt doppeltes + +- Zeichen (--) der Sourcetexte – +ist sehr häufig mit falsch gesetzten Minus-Zeichen zu tauschen + +(siehe link:https://de.wikipedia.org/wiki/Typografische_Zeichen_in_HTML#Striche[Wikipedia]) + +|— +|Gedankenstrich, Geviert-Strich + +/ em dash +|U+2014 +|\— +|`alt (+) 0151` +| +|wird in deutschen Texten selten verwendet + +|… +|Auslassungspunkte + +/ three dot leader +|U+2026 +|\… +|`alt (+) 0133` +|`alt (+) .` +| + +|„ +|Anführung, links unten +|U+201C +|\„ +|`alt (+) 0132` +|`alt (+) shift (+) W` +|nicht in Code-Beispielen verwenden + +|“ +|Anführung, rechts oben +|U+201C +|\“ +|`alt (+) 0147` +|`alt (+) 2` +|nicht in Code-Beispielen verwenden + +|‚ +|einfach Anführung, links unten +|U+201A +|\‚ +|`alt (+) 0130` +|`alt (+) s` +|nicht in Code-Beispielen verwenden + +|‘ +|einfach Anführung, rechts oben +|U+2018 +|\‘ +|`alt (+) 0145` +|`alt (+) #` +|nicht in Code-Beispielen verwenden diff --git a/TRANSLATING.md b/TRANSLATING.md new file mode 100644 index 000000000..efe309bd8 --- /dev/null +++ b/TRANSLATING.md @@ -0,0 +1,105 @@ +# Pro Git Übersetzung (2. Edition) + +Die Übersetzungen werden dezentral verwaltet. Jedes Übersetzungsteam pflegt sein eigenes Projekt. Jede Übersetzung befindet sich in einem eigenen Repository, das Pro Git-Team zieht einfach die Änderungen und baut sie nach Fertigstellung in die Website https://git-scm.com ein. + +## Allgemeine Hinweise zur Übersetzung von Pro Git + +Pro Git ist ein Buch über ein technisches Werkzeug, daher ist die Übersetzung im Vergleich zu einer nicht-technischen Übersetzung schwierig. + +Die folgenden Richtlinien sollen Ihnen auf Ihrem Weg helfen: +* Bevor Sie beginnen, lesen Sie das gesamte Git Pro Buch auf Englisch, damit Sie den Inhalt kennen und mit dem verwendeten Stil vertraut werden. +* Stellen Sie sicher, dass Sie über gute Grundkenntnisse in git verfügen, so dass die Erklärung der Fachbegriffe möglich ist. +* Halten Sie sich an einen gemeinsamen Stil und ein gemeinsames Format für die Übersetzung. +* Lesen und verstehen Sie unbedingt die Grundlagen der [Asciidoc-Formatierung](https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/). Die Nichteinhaltung der asciidoc-Syntax kann zu Problemen beim Erstellen/Kompilieren der für das Buch benötigten pdf-, epub- und html-Dateien führen. + +## Das Buch in eine andere Sprache übersetzen + +### Mithilfe bei einem bestehenden Projekt + +* Suchen Sie in der folgenden Tabelle nach einem bereits vorhandenen Projekt. +* Gehen Sie auf die GitHub-Projektseite. +* Eröffnen Sie ein Issue, stellen Sie sich vor und fragen Sie, wo Sie helfen können. + +| Sprache | GitHub Projektseite | +| :------------- | :------------- | +| العربية | [progit2-ar/progit2](https://github.com/progit2-ar/progit2) | +| Беларуская | [progit/progit2-be](https://github.com/progit/progit2-be) | +| български език | [progit/progit2-bg](https://github.com/progit/progit2-bg) | +| Čeština | [progit-cs/progit2-cs](https://github.com/progit-cs/progit2-cs) | +| English | [progit/progit2](https://github.com/progit/progit2) | +| Español | [progit/progit2-es](https://github.com/progit/progit2-es) | +| فارسی | [progit2-fa/progit2](https://github.com/progit2-fa/progit2) | +| Français | [progit/progit2-fr](https://github.com/progit/progit2-fr) | +| Deutsch | [progit-de/progit2](https://github.com/progit-de/progit2) | +| Ελληνικά | [progit2-gr/progit2](https://github.com/progit2-gr/progit2) | +| Indonesian | [progit/progit2-id](https://github.com/progit/progit2-id) | +| Italiano | [progit/progit2-it](https://github.com/progit/progit2-it) | +| 日本語 | [progit/progit2-ja](https://github.com/progit/progit2-ja) | +| 한국어 | [progit/progit2-ko](https://github.com/progit/progit2-ko) | +| Македонски | [progit2-mk/progit2](https://github.com/progit2-mk/progit2) | +| Bahasa Melayu| [progit2-ms/progit2](https://github.com/progit2-ms/progit2) | +| Nederlands | [progit/progit2-nl](https://github.com/progit/progit2-nl) | +| Polski | [progit2-pl/progit2-pl](https://github.com/progit2-pl/progit2-pl) | +| Português (Brasil) | [progit2-pt-br/progit2](https://github.com/progit2-pt-br/progit2) | +| Русский | [progit/progit2-ru](https://github.com/progit/progit2-ru) | +| Slovenščina | [progit/progit2-sl](https://github.com/progit/progit2-sl) | +| Српски | [progit/progit2-sr](https://github.com/progit/progit2-sr) | +| Tagalog | [progit2-tl/progit2](https://github.com/progit2-tl/progit2) | +| Türkçe | [progit/progit2-tr](https://github.com/progit/progit2-tr) | +| Українська| [progit/progit2-uk](https://github.com/progit/progit2-uk) | +| Ўзбекча | [progit/progit2-uz](https://github.com/progit/progit2-uz) | +| 简体中文 | [progit/progit2-zh](https://github.com/progit/progit2-zh) | +| 正體中文 | [progit/progit2-zh-tw](https://github.com/progit/progit2-zh-tw) | + +### Eine neue Übersetzung beginnen + +Wenn es noch kein Projekt für Ihre Sprache gibt, können Sie eine eigene Übersetzung starten. + +Grundlage Ihrer Arbeit ist die zweite Ausgabe des Buches, die [hier](https://github.com/progit/progit2) verfügbar ist. So sollten Sie vorgehen: + 1. Wählen Sie den richtigen [ISO 639-Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) für Ihre Sprache. + 1. Erstellen Sie eine [GitHub-Organisation](https://help.github.com/articles/creating-a-new-organization-from-scratch/), z.B. `progit2-[your code]` auf GitHub. + 1. Erstellen Sie ein Projekt ``progit2``. + 1. Kopieren Sie die Struktur von progit/progit2 (dieses Projekt) in Ihr Projekt und beginnen Sie mit der Übersetzung. + +### Den Bearbeitungsstatus Ihrer Übersetzung aktualisieren + +Auf https://git-scm.com sind die Übersetzungen in drei Kategorien eingeteilt. Sobald Sie eine dieser Levels erreicht haben, kontaktieren Sie die Betreuer von https://git-scm.com/, damit sie die Änderungen übernehmen können. + +| Kategorie | fertiggestellt | +| :------------- | :------------- | +| Übersetzung begonnen für | Einführung übersetzt, sonst nicht viel. | +| unvollständige Übersetzungen verfügbar in | übersetzt bis Kapitel 6. | +| Vollständige Übersetzung verfügbar in | das Buch ist (fast) vollständig übersetzt. | + +## Kontinuierliche Integration mit Travis CI + +Travis CI ist ein Dienst für [kontinuierliche Integration](https://en.wikipedia.org/wiki/Continuous_integration), der in GitHub integriert werden kann. Travis CI wird verwendet, um sicherzustellen, dass eine Pull-Anforderung den Build oder die Kompilierung nicht unterbricht. Travis CI kann auch kompilierte Versionen des Buches zur Verfügung stellen. + +Die Einrichtung von Travis CI erfordert eine administrative Kontrolle über das Repository. + +### Registrierung für die kontinuierliche Integration von Travis + +1. Ein Travis-Konto [hier](https://travis-ci.org/) einrichten. +1. Registrieren Sie Ihr Projekt in Travis. +Weitere Informationen finden Sie in der [Travis-Dokumentation](https://docs.travis-ci.com/). + +### Einrichten Ihres Repositorys für eine kontinuierliche Integration + +Travis CI scannt das Stammverzeichnis Ihres Projekts nach einer Datei mit dem Namen `.travis.yml` und folgt dem darin enthaltenen „Rezept“. Die gute Nachricht ist: Es gibt bereits eine funktionierende `.travis.yml` Datei im Pro Git 2 Quellcode [hier](https://raw.githubusercontent.com/progit/progit2-pub/master/travis.yml). +Kopieren Sie diese Datei und legen Sie sie in Ihr Arbeitsverzeichnis. Commitieren Sie die .yml-Datei und verschieben Sie sie in Ihr Übersetzungs-Repository; das sollte eine Kompilierung und eine Überprüfung des Inhalts des Buches auslösen. + +## Einrichtung einer Publikationskette für E-Books + +Das ist eine technische Sache, bitte kontaktieren Sie @jnavila, um mit der Veröffentlichung von epub zu beginnen. + +## Abgesehen von Pro Git + +Die Übersetzung des Buches ist der erste Schritt. Sobald das fertig ist, können Sie die Benutzeroberfläche von Git selbst übersetzen. + +Diese Aufgabe erfordert ein besseres technisches Wissen über das Tool als das Buch. Hoffentlich können Sie nach der Übersetzung des gesamten Buchinhalts die in der Anwendung verwendeten Begriffe verstehen. Wenn Sie sich der Aufgabe technisch gewachsen fühlen, ist das Repo [hier](https://github.com/git-l10n/git-po) und Sie müssen nur der [Anleitung](https://github.com/git-l10n/git-po/blob/master/po/README). + +Beachten Sie jedoch, dass + + * Sie speziellere Tools verwenden müssen, um die Lokalisierungs-Po-Dateien zu handhaben (z.B. um sie mit [poedit](https://poedit.net/) zu bearbeiten) und sie zusammenzuführen. Möglicherweise müssen Sie git kompilieren, um Ihre Arbeit zu überprüfen. + * ein grundlegendes Verständnis über die Übersetzung von Anwendungen erforderlich ist, die sich deutlich von der Übersetzung von Büchern unterscheidet. + * das Core-Projekt Git strengere [Vorschriften](https://github.com/git-l10n/git-po/blob/master/Documentation/SubmittingPatches) für die Annahme von Beiträgen anwendet. Achten Sie darauf, diese einzuhalten. diff --git a/TRANSLATION_NOTES.asc b/TRANSLATION_NOTES.asc index 41af29ffa..592ac9bda 100644 --- a/TRANSLATION_NOTES.asc +++ b/TRANSLATION_NOTES.asc @@ -1,121 +1,13 @@ -= Hinweise zur deutschen Übersetzung += Hinweise zur Übersetzung -In diesem Dokument werden alle Informationen rund um die deutsche Übersetzung gesammelt. Hiermit möchten wir beispielsweise festlegen, ob der Leser mit "Du" oder "Sie" angesprochen wird, ob der Erzähler die 1. Person Singular oder die 1. Person Plural verwendet oder wie technische Fachbegriffe übersetzt werden sollen. +Nachdem dieses Repository für die Übersetzung der Arbeit freigegeben wurde, werden in dieser Datei die Hinweise zur Koordination der Übersetzungsarbeit angezeigt. +Zum Beispiel die Standardisierung von Wörtern und Ausdrücken, damit die Arbeit konsistent ist, oder Hinweise darauf, wie der beitragende Prozess zu handhaben ist. -== Übersetzungsfortschritt +Als Übersetzungsmanager können Sie die README-Datei auch ändern oder komplett neu schreiben, mit Anweisungen, die speziell auf Ihre Übersetzung zugeschnitten sind. -Beim Übersetzen sollte, zusätzlich zur eigentlichen Übersetzung, der Fortschritt jedes Kapitels in der Datei link:./status.json[`status.json`] hinterlegt werden. Diese Prozentangabe wird auf verschiedenen Seiten verwendet, um die Leser über den Fortschritt der jeweiligen Übersetzung zu informieren. +In den Dokumenten link:TRANSLATING.md[Pro Git Übersetzung] und link:TRANSLATION_NOTES_DE.asc[Hinweise zur deutschen Übersetzung] finden Sie weitere Informationen. -== Workflow Git +=== Translation Status -Wenn Sie an der deutschen Übersetzung mitarbeiten wollen, können Sie dazu ein link:https://git-scm.com/book/de/v1/Distribuierte-Arbeit-mit-Git-xxx-An-einem-Projekt-mitarbeiten#Kleine,-öffentliche-Projekte[Fork] erstellen und in diesem weiterarbeiten. - -* Bitte erstellen Sie erst einen Pull-Request, wenn Sie ein Arbeitspaket abgeschlossen haben. Bitte beschreiben Sie im Pull-Request, was Ihr zu mergender Branch enthält (neue Übersetzungen, Korrekturen usw.). - -* Wir werden Ihren Beitrag prüfen und ein weiterer Helfer wird Ihr Ergebnis Korrektur lesen (Review). Das kann dazu führen, dass Sie Ihre Arbeit noch einmal überarbeiten müssen. Bitte sehen Sie das Review als positive Hilfestellung, damit das Ergebnis insgesamt besser wird, und nehmen Sie die Kritik nicht negativ auf. Wir wollen damit sicherstellen, dass die deutsche Übersetzung einheitlicher wird und in einer guten Qualität zur Verfügung steht. Wenn alles passt, nehmen wir das Ergebnis in den Hauptzweig auf und veröffentlichen es für die bekannten Seiten. - -* Wenn Ihr Ergebnis sehr weit vom Master-Zweig abweicht, kann es passieren, dass wir Sie um einen link:https://git-scm.com/book/de/v1/Git-Branching-Rebasing[Rebase] bitten. - -* Da bei der deutschen Übersetzung ausschließlich deutschsprachige Mitarbeiter mitwirken, sollte die Commit-Beschreibung auf Deutsch erfolgen. Bitte wenden Sie die üblichen Git Commit-Beschreibungskonventionen an. - -== Workflow Übersetzung - -* Falls Sie einen Abschnitt übersetzen möchten, der noch nicht übersetzt wurde, sollten Sie nach der Übersetzung den englischen Text entfernen. Bitte entfernen Sie den englischen Text nur für die Passagen, die Sie auch tatsächlich bereits übersetzt haben. - -* Kommandozeilenausgaben sollten so übersetzt werden, dass sie mit der deutschen Version von Git übereinstimmen. Im Zweifel belassen Sie bitte die Kommandozeilenausgabe in Englisch. - -== Allgemeine Regeln - -* Der Leser wird formal mit „Sie“ angesprochen, wobei das „Sie“ auch großgeschrieben wird. Bitte beachten Sie dies auch bei Possessivpronomen, wie beispielsweise „Ihr“, „Ihre“ usw. Siehe hierzu auch link:http://www.duden.de/sprachwissen/sprachratgeber/gross-oder-kleinschreibung-von--em-du-du--em--und--em-ihr-ihr--em--1[folgender Link]. Andere Sprachen verwenden ebenfalls die formelle Form, wie link:https://github.com/progit/progit2/issues/151[hier] beschrieben. - -== Schreibweise und Übersetzung von Fachbegriffen - -Die Übersetzungen orientieren sich an der deutschen Übersetzung der Programmdatei von git (`/usr/bin/git` beziehungsweise `git.exe`). - -Wenn ein Fachbegriff in dieser Liste fehlt, überprüfen Sie bitte, ob dieser in der Git-Programmdatei verwendet wird (siehe hierzu link:https://github.com/git/git/blob/master/po/de.po[folgender Link]). - -Bitte erfinden Sie keine neue deutsche Übersetzung, sondern orientieren Sie sich bitte an der nachfolgenden Liste oder an der deutschen Übersetzung der Git-Programmdatei. - -=== A – D - -[width="100%", frame="topbot", options="header,footer"] -|============================================================================== -|Englisch|Deutsch -|Branch| -Branch; Singular: der Branch; Plural: die Branches; Alternativ kann auch die deutsche Übersetzung „Zweig“ verwendet werden -|Branchname| -Branchname; Singular: der Branchname; Plural: die Branchnamen -|To clone| -Klonen; Ein Repository klonen -|Clone| -Klon; Singular: der Klon; Plural: – -|Commit| -Commit; Singular: der Commit; Plural: die Commits -|To commit| -Committen; er/sie committet; wir committen; Alternativ: Einchecken -|Commit date| -Commit-Datum; Singular: das Commit-Datum; Plural: die Commit-Daten; Alternativ: -Datum eines Commits -|Commit id| -Commit-ID; Singular: die Commit-ID; Plural: die Commit-IDs; Alternativ: -Commit-Referenz -|Commit message| -Commit-Beschreibung; Singular: die Commit-Beschreibung; Plural: die Commit-Beschreibungen; -Alternativ: die Commit-Nachricht -|Diff| -Diff; Singular: der Diff; Plural: die Diffs; Alternativ: der Vergleich, Ausgabe eines Vergleichs -|============================================================================== - -=== E – Q - -[width="100%", frame="topbot", options="header,footer"] -|============================================================================== -|Englisch|Deutsch -|HEAD| -HEAD; Singular: der HEAD; Plural: –; Oft kann HEAD ohne Artikel verwendet werden -|Index| -Staging-Area; Singular: die Staging-Area; Alternativ: der Index -|============================================================================== - -=== R – T - -[width="100%", frame="topbot", options="header,footer"] -|============================================================================== -|Englisch|Deutsch -|Repository| -Repository; Singular: das Repository; Plural: die Repositorys; **Nicht** Repositor**ie**s, -siehe hierzu auch link:http://www.duden.de/sprachwissen/sprachratgeber/crashkurs--in-25-schritten-zur-neuen-rechtschreibung[folgender Link] -|Remote repository| -Remote-Repository; Singular: das Remote-Repository; Plural: die Remote-Repositorys -|SHA1 hash| -SHA1 Hash; Singular: der SHA1 Hash; Plural: die SHA1 Hashes -|Snapshot| -Snapshot; Singular: der Snapshot; Plural: die Snapshots; Alternativ kann auch Schnappschuss verwendet werden, häufiger verwendet man allerdings den englischen Begriff -|To stage| -Zum Commit vormerken; Zur Staging-Area hinzufügen -|Staged| -Zum Commit vorgemerkt; Zur Staging-Area hinzugefügt -|Staging area| -Staging-Area; Alternativ: Index -|Stash| -Stash; Singular: der Stash; Plural: die Stashes -|To stash| -Zum Stash hinzufügen -|To track| -Versionieren; Zur Versionsverwaltung hinzufügen -|============================================================================== - -=== U – Z - -[width="100%", frame="topbot", options="header,footer"] -|============================================================================== -|Englisch|Deutsch -|To unstage| -Aus der Staging-Area entfernen -|Version control| -Versionsverwaltung; Singular: die Versionsverwaltung; Prinzipiell ist auch Versionskontrolle möglich, allerdings wird heutzutage meist der Begriff Versionsverwaltung verwendet -|============================================================================== - -== Als Maintainer helfen - -Wenn Sie nicht nur zur Übersetzung beitragen möchten, sondern uns auch bei der Koordination unterstützen wollen, dann melden Sie sich bitte bei einem Maintainer. +Wenn die Arbeit übersetzt ist, aktualisieren Sie bitte die Datei `status.json`, um den groben Prozentsatz der Fertigstellung jeder Datei anzugeben. +Dies wird auf verschiedenen Seiten gezeigt, um den Leuten mitzuteilen, wie viel Arbeit noch zu tun ist. diff --git a/TRANSLATION_NOTES_DE.asc b/TRANSLATION_NOTES_DE.asc new file mode 100644 index 000000000..99f8bb33d --- /dev/null +++ b/TRANSLATION_NOTES_DE.asc @@ -0,0 +1,155 @@ += Hinweise zur deutschen Übersetzung + +In diesem Dokument werden alle Informationen rund um die deutsche Übersetzung gesammelt. Hiermit möchten wir beispielsweise festlegen, ob der Leser mit „Du“ oder „Sie“ angesprochen wird, ob der Erzähler die 1. Person Singular oder die 1. Person Plural verwendet oder wie technische Fachbegriffe übersetzt werden sollen. + +== Übersetzungsfortschritt + +Beim Übersetzen sollte, zusätzlich zur eigentlichen Übersetzung, der Fortschritt jedes Kapitels in der Datei link:./status.json[`status.json`] hinterlegt werden. Diese Prozentangabe wird auf verschiedenen Seiten verwendet, um die Leser über den Fortschritt der jeweiligen Übersetzung zu informieren. + +== Workflow Git + +Wenn Sie an der deutschen Übersetzung mitarbeiten wollen, können Sie dazu ein link:https://git-scm.com/book/de/v1/Distribuierte-Arbeit-mit-Git-xxx-An-einem-Projekt-mitarbeiten#Kleine,-öffentliche-Projekte[Fork] erstellen und in diesem weiterarbeiten. + +* Bitte erstellen Sie erst dann einen Pull-Request, wenn Sie ein Arbeitspaket abgeschlossen haben. Bitte beschreiben Sie im Pull-Request, was Ihr zu mergender Branch enthält (neue Übersetzungen, Korrekturen usw.). + +* Wir werden Ihren Beitrag prüfen und ein weiterer Helfer wird Ihr Ergebnis Korrektur lesen (Review). Das kann dazu führen, dass Sie Ihre Arbeit noch einmal überarbeiten müssen. Bitte sehen Sie das Review als positive Hilfestellung, damit das Ergebnis insgesamt besser wird, und nehmen Sie die Kritik nicht negativ auf. Wir wollen damit sicherstellen, dass die deutsche Übersetzung einheitlicher wird und in einer guten Qualität zur Verfügung steht. Wenn alles passt, nehmen wir das Ergebnis in den Hauptzweig auf und veröffentlichen es für die bekannten Seiten. + +* Wenn Ihr Ergebnis sehr weit vom Master-Zweig abweicht, kann es passieren, dass wir Sie um einen link:https://git-scm.com/book/de/v1/Git-Branching-Rebasing[Rebase] bitten. + +* Da bei der deutschen Übersetzung ausschließlich deutschsprachige Mitarbeiter mitwirken, sollte die Commit-Beschreibung auf Deutsch erfolgen. Bitte wenden Sie die üblichen Git Commit-Beschreibungskonventionen an. + +== Übersetzungs-Workflow + +* Falls Sie einen Abschnitt übersetzen möchten, der noch nicht übersetzt wurde, sollten Sie nach der Übersetzung den englischen Text entfernen. Bitte entfernen Sie den englischen Text nur für die Passagen, die Sie auch tatsächlich bereits übersetzt haben. + +* Kommandozeilenausgaben sollten so übersetzt werden, dass sie mit der deutschen Version von Git übereinstimmen. Im Zweifel belassen Sie bitte die Kommandozeilenausgabe in Englisch. + +== Allgemeine Regeln + +* Der Leser wird formal mit „Sie“ angesprochen, wobei das „Sie“ auch großgeschrieben wird. Bitte beachten Sie dies auch bei Possessivpronomen, wie beispielsweise „Ihr“, „Ihre“ usw. gilt. Siehe hierzu auch link:http://www.duden.de/sprachwissen/sprachratgeber/gross-oder-kleinschreibung-von--em-du-du--em--und--em-ihr-ihr--em--1[folgender Link]. Andere Sprachen verwenden ebenfalls die formelle Form, wie link:https://github.com/progit/progit2/issues/151[hier] beschrieben. + +== Schreibweise und Übersetzung von Fachbegriffen + +=== Typografie + +Die typografisch korrekte Schreibweise in deutschen Texten enthält ein paar Besonderheiten, die sich optisch doch recht stark von der Schreibweise in englischen Texten unterscheiden. +Um für die Leser ein möglichst vertrautes Schriftbild zu erreichen, sollten wir die folgenden Hinweise konsequent umsetzen. + +Leider ist es nicht möglich einige dieser Sonderzeichen mit der Standardtastatur direkt zu erreichen. +Glücklicherweise können diese Sonderzeichen aber über einen UTF-Code identifiziert und damit übernommen werden. + +Unter Windows (schon seit dem Urahn Windows 3.11) gibt man mit `alt + ` einen String ein, der das Sonderzeichen ausgibt (eine grafische Auflistung kann man mit dem System-Tool „Zeichentabelle“ erhalten). + +Für MacOS X ist link:https://www.die-tastenkombination.de/tastenkombinationen-mac-os-sonderzeichen.html[hier] und link:https://www.maclife.de/tipps-tricks/mac-os-x/drei-wege-zum-sonderzeichen-unter-os-x[hier] eine Auflistung bzw. eine Anleitung zu sehen. Außerdem können mit dem System-Tool „Zeichenübersicht“ alle verfügbaren Zeichen angezeigt werden. + +Bei Linux gibt es zu viele Distributionen und verschiedene Desktop-GUIs, die jeweils unterschiedliche Vorgehensweisen erfordern, um sie in diesem Rahmen erschöpfend auflisten zu können. + +Für die häufigsten Sonderzeichen stellen wir link:Special_Characters.asc[hier] eine Tabelle zur Verfügung, aus der man per `copy+paste` die Sonderzeichen in eigene Texte übernehmen kann. + +=== Begriffe + +Die Übersetzungen orientieren sich an der deutschen Übersetzung der Programmdatei von git (`/usr/bin/git` beziehungsweise `git.exe`). + +Wenn ein Fachbegriff in der folgenden Liste fehlt, überprüfen Sie bitte, ob dieser in der Git-Programmdatei verwendet wird (siehe hierzu link:https://github.com/git/git/blob/master/po/de.po[folgenden Link]). + +Bitte erfinden Sie keine neue deutsche Übersetzung, sondern orientieren Sie sich bitte an der nachfolgenden Liste oder an der deutschen Übersetzung der Git-Programmdatei. + +=== A – D + +[width="100%", frame="topbot", options="header,footer"] +|============================================================================== +|Englisch|Deutsch +|Branch| +Branch; Singular: der Branch; Plural: die Branches; Alternativ kann auch die deutsche Übersetzung „Zweig“ verwendet werden +|Branchname| +Branchname; Singular: der Branchname; Plural: die Branchnamen +|To clone| +Klonen; Ein Repository klonen +|Clone| +Klon; Singular: der Klon; Plural: – +|Commit| +Commit; Singular: der Commit; Plural: die Commits +|To commit| +Committen; er/sie committet; wir committen; Alternativ: Einchecken +|Commit date| +Commit-Datum; Singular: das Commit-Datum; Plural: die Commit-Daten; Alternativ: +Datum eines Commits +|Commit id| +Commit-ID; Singular: die Commit-ID; Plural: die Commit-IDs; Alternativ: +Commit-Referenz +|Commit message| +Commit-Beschreibung; Singular: die Commit-Beschreibung; Plural: die Commit-Beschreibungen; +Alternativ: die Commit-Nachricht +|Diff| +Diff; Singular: der Diff; Plural: die Diffs; Alternativ: der Vergleich, Ausgabe eines Vergleichs +|============================================================================== + +=== E – J + +[width="100%", frame="topbot", options="header,footer"] +|============================================================================== +|Englisch|Deutsch +|HEAD| +HEAD; Singular: der HEAD; Plural: –; Oft kann HEAD ohne Artikel verwendet werden +|Index| +Staging-Area; Singular: die Staging-Area; Alternativ: der Index +|============================================================================== + +=== K – Q + +[width="100%", frame="topbot", options="header,footer"] +|============================================================================== +|Englisch|Deutsch +|to merge| +mergen, auch zusammenführen oder verschmelzen +|Merging| +Merging +|============================================================================== + + +=== R – T + +[width="100%", frame="topbot", options="header,footer"] +|============================================================================== +|Englisch|Deutsch +|remote| +entfernt, auch extern (je nach Kontext) oder Remote-... +|Repository| +Repository; Singular: das Repository; Plural: die Repositorys; **Nicht** Repositor**ie**s, +siehe hierzu auch link:http://www.duden.de/sprachwissen/sprachratgeber/crashkurs--in-25-schritten-zur-neuen-rechtschreibung[folgender Link] +|Remote repository| +Remote-Repository; Singular: das Remote-Repository; Plural: die Remote-Repositorys +|SHA1 hash| +SHA1 Hash; Singular: der SHA1 Hash; Plural: die SHA1 Hashes +|Snapshot| +Snapshot; Singular: der Snapshot; Plural: die Snapshots; Alternativ kann auch Schnappschuss verwendet werden, häufiger verwendet man allerdings den englischen Begriff +|to stage| +zum Commit vormerken; zur Staging-Area hinzufügen +|staged| +zum Commit vorgemerkt; zur Staging-Area hinzugefügt +|Staging area| +Staging-Area; Alternativ: Index +|stash| +Stash; Singular: der Stash; Plural: die Stashes +|to stash| +zum Stash hinzufügen, auch bunkern (ev. mit Hinweis: engl. stashed, je nach Kontext) +|to track| +versionieren; Zur Versionsverwaltung hinzufügen, auch verfolgen (ev. mit Hinweis: engl. tracked, je nach Kontext) +|============================================================================== + +=== U – Z + +[width="100%", frame="topbot", options="header,footer"] +|============================================================================== +|Englisch|Deutsch +|To unstage| +Aus der Staging-Area entfernen +|Version control| +Versionsverwaltung; Singular: die Versionsverwaltung; Prinzipiell ist auch Versionskontrolle möglich, allerdings wird heutzutage meist der Begriff Versionsverwaltung verwendet +|working tree| +Verzeichnisbaum +|============================================================================== + +== Als Maintainer helfen + +Wenn Sie nicht nur zur Übersetzung beitragen möchten, sondern uns auch bei der Koordination unterstützen wollen, dann melden Sie sich bitte bei einem Maintainer. diff --git a/book/01-introduction/1-introduction.asc b/book/01-introduction/1-introduction.asc deleted file mode 100644 index a9b947490..000000000 --- a/book/01-introduction/1-introduction.asc +++ /dev/null @@ -1,26 +0,0 @@ -[[_getting_started]] -== Los geht's - -In diesem Kapitel wird es darum gehen, wie man mit Git loslegen kann. -Sie werden lernen, wozu Versionsverwaltungssysteme gut sind und wie Sie Git auf verschiedenen Systemen installieren und konfigurieren können, sodass Sie in der Lage sind, die ersten Schritte mit Git zu tun. -Am Ende dieses Kapitels sollten Sie verstanden haben, wozu Git gut ist und weshalb man es verwenden sollte und Sie sollten in der Lage sein, mit Git loslegen zu können. - -include::sections/about-version-control.asc[] - -include::sections/history.asc[] - -include::sections/basics.asc[] - -include::sections/command-line.asc[] - -include::sections/installing.asc[] - -include::sections/first-time-setup.asc[] - -include::sections/help.asc[] - -=== Zusammenfassung - -Sie sollten jetzt ein grundlegendes Verständnis davon haben, was Git ist und wie es sich von einer zentralisierten Versionsverwaltung unterscheidet, welche Sie früher vielleicht schon einmal verwendet haben. -Außerdem sollte Ihr Rechner nun eingerichtet und mit einem persönlichen Profil versehen sein, um mit Git loslegen zu können. -Jetzt ist es an der Zeit, auf einige Git Grundlagen einzugehen. diff --git a/book/01-introduction/images/areas.png b/book/01-introduction/images/areas.png deleted file mode 100644 index da98fb034..000000000 Binary files a/book/01-introduction/images/areas.png and /dev/null differ diff --git a/book/01-introduction/images/centralized.png b/book/01-introduction/images/centralized.png deleted file mode 100644 index 9aa3e902c..000000000 Binary files a/book/01-introduction/images/centralized.png and /dev/null differ diff --git a/book/01-introduction/images/deltas.png b/book/01-introduction/images/deltas.png deleted file mode 100644 index 47904edb0..000000000 Binary files a/book/01-introduction/images/deltas.png and /dev/null differ diff --git a/book/01-introduction/images/distributed.png b/book/01-introduction/images/distributed.png deleted file mode 100644 index 53cfcaebc..000000000 Binary files a/book/01-introduction/images/distributed.png and /dev/null differ diff --git a/book/01-introduction/images/local.png b/book/01-introduction/images/local.png deleted file mode 100644 index 1779acfbf..000000000 Binary files a/book/01-introduction/images/local.png and /dev/null differ diff --git a/book/01-introduction/images/snapshots.png b/book/01-introduction/images/snapshots.png deleted file mode 100644 index 1036a4245..000000000 Binary files a/book/01-introduction/images/snapshots.png and /dev/null differ diff --git a/book/01-introduction/sections/about-version-control.asc b/book/01-introduction/sections/about-version-control.asc index bb608d189..68a68b92b 100644 --- a/book/01-introduction/sections/about-version-control.asc +++ b/book/01-introduction/sections/about-version-control.asc @@ -1,7 +1,7 @@ === Was ist Versionsverwaltung? (((Versionsverwaltung))) -Was ist "Versionsverwaltung", und warum sollten Sie sich dafür interessieren? +Was ist „Versionsverwaltung“, und warum sollten Sie sich dafür interessieren? Versionsverwaltung ist ein System, welches die Änderungen an einer oder einer Reihe von Dateien über die Zeit hinweg protokolliert, sodass man später auf eine bestimmte Version zurückgreifen kann. Die Dateien, die in den Beispielen in diesem Buch unter Versionsverwaltung gestellt werden, enthalten Quelltext von Software, tatsächlich kann in der Praxis nahezu jede Art von Datei per Versionsverwaltung nachverfolgt werden. @@ -13,19 +13,17 @@ All diese Vorteile erhält man für einen nur sehr geringen, zusätzlichen Aufwa ==== Lokale Versionsverwaltung (((Versionswerwaltung,lokal))) - Viele Menschen betreiben Versionsverwaltung, indem sie einfach all ihre Dateien in ein separates Verzeichnis kopieren (die Schlaueren darunter verwenden ein Verzeichnis mit Zeitstempel im Namen). Diese Vorgehensweise ist sehr weit verbreitet und wird gern verwendet, weil sie so einfach ist. Aber sie ist eben auch unglaublich fehleranfällig. Man arbeitet sehr leicht im falschen Verzeichnis, bearbeitet damit die falschen Dateien oder überschreibt Dateien, die man eigentlich nicht überschreiben wollte. Aus diesem Grund, haben Programmierer bereits vor langer Zeit, lokale Versionsverwaltungssysteme entwickelt, die alle Änderungen an allen relevanten Dateien in einer Datenbank verwalten. -.Lokale Versionsverwaltung. +.Lokale Versionsverwaltung image::images/local.png[Local version control diagram] Eines der populäreren Versionsverwaltungssysteme war RCS, welches auch heute noch mit vielen Computern ausgeliefert wird. -Sogar das bekannte Betriebssystem Mac OS X unterstützt den Befehl `rcs`, vorausgesetzt man hat die Developer Tools installiert. -RCS arbeitet nach dem Prinzip, dass für jede Änderung ein Patch (ein Patch umfasst alle Änderungen an einer oder mehreren Dateien) in einem speziellen Format auf der Festplatte gespeichert wird. Um eine bestimmte Version einer Datei wiederherzustellen, wendet es alle Patches bis zur gewünschten Version an und rekonstruiert damit die Datei in der gewünschten Version. +https://www.gnu.org/software/rcs/[RCS] arbeitet nach dem Prinzip, dass für jede Änderung ein Patch (ein Patch umfasst alle Änderungen an einer oder mehreren Dateien) in einem speziellen Format auf der Festplatte gespeichert wird. Um eine bestimmte Version einer Datei wiederherzustellen, wendet es alle Patches bis zur gewünschten Version an und rekonstruiert damit die Datei in der gewünschten Version. ==== Zentrale Versionsverwaltung @@ -35,7 +33,7 @@ Um dieses Problem zu lösen, wurden zentralisierte Versionsverwaltungssysteme en Diese Systeme, wozu beispielsweise CVS, Subversion und Perforce gehören, basieren auf einem zentralen Server, der alle versionierten Dateien verwaltet. Die Clients können die Dateien von diesem zentralen Ort abholen und auf ihren PC übertragen. Den Vorgang des Abholens nennt man Auschecken (engl. to check out). (((CVS)))(((Subversion)))(((Perforce))) Diese Art von System war über viele Jahre hinweg der Standard für Versionsverwaltungssysteme. -.Zentrale Versionsverwaltung. +.Zentrale Versionsverwaltung image::images/centralized.png[Centralized version control diagram] Dieser Ansatz hat viele Vorteile, besonders gegenüber lokalen Versionsverwaltungssystemen. @@ -51,13 +49,13 @@ Lokale Versionskontrollsysteme haben natürlich dasselbe Problem: Wenn man die H ==== Verteilte Versionsverwaltung (((Versionsverwaltung, verteilt))) -Und an dieser Stelle kommen verteilte Versionsverwaltungssysteme (engl. Distributed Version Control System, DVCS) ins Spiel. +Und an dieser Stelle kommen verteilte Versionsverwaltungssysteme (engl. Distributed Version Control System, DVCS) ins Spiel. In einem DVCS (wie z.B. Git, Mercurial, Bazaar oder Darcs) erhalten Anwender nicht einfach nur den jeweils letzten Zustand des Projektes von einem Server: Sie erhalten stattdessen eine vollständige Kopie des Repositorys. Auf diese Weise kann, wenn ein Server beschädigt wird, jedes beliebige Repository von jedem beliebigen Anwenderrechner zurückkopiert werden und der Server so wiederhergestellt werden. Jede Kopie, ein sogenannter Klon (engl. clone), ist ein vollständiges Backup der gesamten Projektdaten. -.Verteilte Versionsverwaltung. +.Verteilte Versionsverwaltung image::images/distributed.png[Distributed version control diagram] Darüber hinaus können derartige Systeme hervorragend mit verschiedenen externen Repositorys, sogenannten Remote-Repositorys, umgehen, sodass man mit verschiedenen Gruppen von Leuten simultan auf verschiedene Art und Weise, an einem Projekt zusammenarbeiten kann. -Damit ist es möglich, verschiedene Arten von Arbeitsabläufen zu erstellen und anzuwenden, welche mit zentralisierten Systemen nicht möglich wären. Dazu gehören zum Beispiel hierarchische Arbeitsabläufe. \ No newline at end of file +Damit ist es möglich, verschiedene Arten von Arbeitsabläufen zu erstellen und anzuwenden, welche mit zentralisierten Systemen nicht möglich wären. Dazu gehören zum Beispiel hierarchische Arbeitsabläufe. diff --git a/book/01-introduction/sections/basics.asc b/book/01-introduction/sections/basics.asc deleted file mode 100644 index fc8870d35..000000000 --- a/book/01-introduction/sections/basics.asc +++ /dev/null @@ -1,129 +0,0 @@ -=== Git Grundlagen - -Was also ist Git, in kurzen Worten? -Es ist wichtig, den folgenden Abschnitt zu verstehen, in dem es um die grundlegenden Konzepte von Git geht. Das wird Sie in die Lage versetzen, Git einfacher und effektiver anzuwenden. -Versuchen Sie Ihr vorhandenes Wissen über andere Versionsverwaltungssysteme, wie Subversion oder Perforce, beiseite zu schieben, während Sie Git kennenlernen. Wenn Sie diesen Ratschlag befolgen, wird es Ihnen an vielen Stellen leichter fallen und die feinen Unterschiede zu anderen Versionsverwaltungssysteme werden Sie nicht so einfach durcheinanderbringen. -Git speichert und verwaltet Information deutlich anders als andere Systeme, auch wenn die Benutzerschnittstelle relativ ähnlich wirkt. Diese Unterschiede zu verstehen wird Ihnen helfen, Verwirrung bei der Anwendung von Git zu vermeiden.(((Subversion)))(((Perforce))) - -==== Snapshots und nicht die Unterschiede - -Der Hauptunterschied zwischen Git und anderen Versionsverwaltungssystemen (insbesondere auch Subversion und vergleichbare Systeme) besteht in der Art und Weise wie Git die Daten betrachtet. -Die meisten anderen Systeme speichern Information, als eine fortlaufende Liste von Änderungen an Dateien (es werden die Unterschiede gesammelt und gespeichert). -Diese Systeme (CVS, Subversion, Perforce, Bazaar usw.) betrachten die Informationen, die sie verwalten, als eine Menge von Dateien und die Änderungen, die über die Zeit hinweg an einzelnen Dateien vorgenommen werden. - -.Speichern von Daten als Änderung an einzelnen Dateien auf Basis einer Ursprungsdatei. -image::images/deltas.png[Storing data as changes to a base version of each file.] - -Git arbeitet nicht auf diese Art und Weise. -Stattdessen betrachtet Git seine Daten eher als eine Reihe von Snapshots eines Mini-Dateisystems. -Jedes Mal, wenn Sie committen, das heißt den gegenwärtigen Status Ihres Projekts als eine Version in Git speichern, sichert Git den Zustand sämtlicher Dateien in diesem Moment und macht sozusagen ein Schnappschuss (engl. Snapshot) von all Ihren Daten. Zusätzlich speichert Git eine Referenz auf diesen Snapshot. -Um dies möglichst effizient und schnell tun zu können, kopiert Git unveränderte Dateien nicht, sondern legt lediglich eine Verknüpfung zu der vorherigen Version der Datei an. -Das folgende Bild soll diese Vorgehensweise verdeutlichen. - -.Git speichert die Daten-Historie eines Projekts in Form von Snapshots. -image::images/snapshots.png[Git stores data as snapshots of the project over time.] - -Dies ist ein wichtiger Unterschied zwischen Git und praktisch allen anderen Versionsverwaltungssystemen. -In Git wurden daher fast alle Aspekte der Versionsverwaltung neu überdacht, die in anderen Systemen mehr oder weniger von ihrer jeweiligen Vorgängergeneration übernommen worden waren. -Git arbeitet im Großen und Ganzen eher wie ein mit einigen unglaublich mächtigen Werkzeugen ausgerüstetes Mini-Dateisystem, statt nur als Versionsverwaltungssystem. Auf einige der Vorteile, die es mit sich bringt, Daten in dieser Weise zu verwalten, werden wir in Kapitel <<_git_branching>> eingehen, wenn wir das Git Branching Konzept kennenlernen. - -==== Fast jede Funktion arbeitet lokal - -Die meisten Befehle in Git benötigen nur die lokalen Dateien und Ressourcen auf einem PC, um zu funktionieren. In erster Linie werden keine Informationen von einem anderen Rechner im Netzwerk benötigt. -Wenn Sie bisher mit einem CVCS gearbeitet haben, das für die meisten Operationen einen langsamen Netzwerkzugriff benötigt hat, dann wird dieser Aspekt Sie im Glauben lassen, dass Ihr PC auf einmal mit Lichtgeschwindigkeit ausgestattet wurde. -Die allermeisten Operationen können nahezu ohne jede Verzögerung ausgeführt werden, da die vollständige Historie eines Projekts bereits auf dem jeweiligen Rechner verfügbar ist. - -Um beispielsweise die Historie des Projekts zu durchsuchen, braucht Git sie nicht von einem externen Server zu holen – es liest diese einfach aus der lokalen Datenbank. -Das heißt, die vollständige Projekthistorie ist ohne jede Verzögerung verfügbar. -Wenn man sich die Änderungen einer aktuellen Version einer Datei im Vergleich zu vor einem Monat, anschauen möchte, dann kann Git den Stand von vor einem Monat in der lokalen Historie nachschlagen und einen lokalen Vergleich zur vorliegenden Datei durchführen. Für diesen Anwendungsfall benötigt Git keinen externen Server, weder um Dateien dort nachzuschlagen, noch um Unterschiede dort bestimmen zu lassen. - -Dies bedeutet natürlich außerdem, dass es fast nichts gibt, was man nicht tun kann, nur weil man gerade offline ist oder keinen Zugriff auf ein VPN hat. -Wenn man also gerade im Flugzeug oder Zug ein wenig arbeiten will, kann man problemlos seine Arbeit einchecken und dann wenn man wieder mit einem Netzwerk verbunden ist, die Dateien auf einen Server hochladen. -Wenn man zu Hause sitzt, aber der VPN Client gerade mal wieder nicht funktioniert, kann man immer noch arbeiten. -Bei vielen anderen Systemen wäre dies unmöglich oder äußerst kompliziert umzusetzen. -Wenn man zum Beispiel mit Perforce arbeitet, kann man nicht sonderlich viel tun, solange man nicht mit dem Server verbunden ist. In Subversion und CVS kann man in diesem Fall zwar Dateien bearbeiten, aber das Einchecken der Daten ist nicht möglich, da der entsprechende Server und damit auch die Datenbank offline sind. -Das mag auf den ersten Blick nicht nach einem großen Problem aussehen, aber Sie werden überrascht sein, was für einen großen Unterschied das ausmachen kann. - -==== Git stellt Integrität sicher - -Von allen zu speichernden Daten berechnet Git Prüfsummen (engl. checksum) und speichert diese als Referenz zusammen mit den Daten ab. -Das macht es unmöglich, dass sich Inhalte von Dateien oder Verzeichnissen ändern, ohne dass Git das mitbekommt. -Git basiert auf dieser Funktionalität und sie ist ein integraler Teil der Git Philosophie. -Man kann Informationen deshalb z.B. nicht während der Übermittlung verlieren oder unwissentlich beschädigte Dateien verwenden, ohne dass Git in der Lage wäre, dies festzustellen. - -Der Mechanismus, den Git verwendet, um diese Prüfsummen zu erstellen, heißt SHA-1 Hash.(((SHA-1))) -Eine solche Prüfsumme ist eine 40 Zeichen lange Zeichenkette, die aus hexadezimalen Zeichen (0-9 und a-f) besteht und wird von Git aus den Inhalten einer Datei oder Verzeichnisstruktur berechnet. Ein SHA-1 Hash sieht wie folgt aus: - -[source] ----- -24b9da6552252987aa493b52f8696cd6d3b00373 ----- - -Dieses Hashes begegnen einem überall bei der Arbeit, weil sie so ausgiebig von Git genutzt werden. -Git speichert sogar alle Informationen in der Datenbank auf Basis dieser Hashes. Statt eine Datei über den Dateinamen zu referenzieren, verwendet Git den Hash dafür. - -==== Git hängt normalerweise nur Daten an, und löscht sie nicht - -Fast alle in Git verfügbaren Befehle, fügen Daten jeweils nur zur internen Git Datenbank hinzu und entfernen keine Daten aus der Datenbank. -Deshalb ist es sehr schwer, das System dazu zu bewegen, irgendetwas zu tun, das nicht wieder rückgängig zu machen ist, oder dazu, Daten in irgendeiner Form zu löschen. -Wie in jedem anderen VCS, kann man in Git Daten verlieren oder durcheinander bringen, solange man sie noch nicht eingecheckt hat. Aber sobald man einen Schnappschuss in Git eingecheckt hat, ist es sehr schwierig, diese Daten wieder zu verlieren, insbesondere wenn man regelmäßig seine lokale Datenbank auf ein anderes Repository hochlädt. - -Unter anderem deshalb macht es so viel Spaß mit Git zu arbeiten. Man weiß genau, man kann ein wenig experimentieren, ohne befürchten zu müssen, irgendetwas zu zerstören oder durcheinander zu bringen. -Wer sich genauer dafür interessiert, wie Git Daten speichert und wie man Daten, die scheinbar verloren sind, wiederherstellen kann, dem wird das Kapitel <<_undoing>> ans Herz gelegt. - -==== Die drei Zustände - -Jetzt heißt es aufgepasst. -Es folgt die wichtigste Information, die man sich merken muss, wenn man Git erlernen und dabei Fallstricke vermeiden will. -Git definiert drei Hauptzustände, in denen sich eine Datei befinden kann: Committet (engl. committed), geändert (engl. modified) und für Commit vorgemerkt (engl. staged). -Committet bedeutet, dass die Daten sicher in der lokalen Datenbank gespeichert sind. -Geändert bedeutet, dass eine Datei geändert, aber noch nicht in die lokale Datenbank eingecheckt wurde. -Für Commit vorgemerkt bedeutet, dass eine geänderte Datei in ihrem gegenwärtigen Zustand für den nächsten Commit vorgemerkt ist. - -<<<<<<< HEAD -Das führt uns zu den drei Hauptbereichen eines Git Projektes: das Git Verzeichnis, das Arbeitsverzeichnis und die sogenannte Staging-Area. - -.Arbeitsverzeichnis, Staging-Area und Git Verzeichnis. -image::images/areas.png["Working directory, staging area, and Git directory."] -======= -This leads us to the three main sections of a Git project: the Git directory, the working tree, and the staging area. - -.Working tree, staging area, and Git directory. -image::images/areas.png["Working tree, staging area, and Git directory."] ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 - -Das Git Verzeichnis ist der Ort, an dem Git Metadaten und die lokale Datenbank für ein Projekt sichert. -Dies ist der wichtigste Teil von Git, und dieser Teil wird kopiert, wenn man ein Repository von einem anderen Rechner klont. - -<<<<<<< HEAD -Das Arbeitsverzeichnis ist ein einzelnes Abbild einer spezifischen Version des Projektes. -Die dort enthaltenen Dateien werden aus der komprimierten Datenbank geholt und auf der Festplatte in einer Form gespeichert, sodass man sie nutzen oder bearbeiten kann. -======= -The working tree is a single checkout of one version of the project. -These files are pulled out of the compressed database in the Git directory and placed on disk for you to use or modify. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 - -Die Staging Area ist einfach eine Datei, normalerweise befindet sich diese im Git Verzeichnis, in der vorgemerkt wird, welche Änderungen der nächste Commit umfassen soll. -Manchmal wird dieser Ort auch als ``Index'' bezeichnet, aber der Begriff Staging-Area ist der gängigere. - -Die grundlegenden Arbeitsschritte beim Einchecken sind in etwa folgende: - -<<<<<<< HEAD -1. Man ändert die zu bearbeitenden Dateien im Arbeitsverzeichnis -2. Man merkt die Dateien für einen Commit vor, fügt also einen Schnappschuss der Dateien der Staging-Area hinzu -3. Man führt einen Commit aus, wodurch der in der Staging-Area vorgemerkte Schnappschuss dauerhaft im Git Verzeichnis gespeichert wird - -Wenn eine bestimmte Version einer Datei im Git Verzeichnis liegt, gilt sie als committet, oder anders ausgedrückt, sie gilt als eingecheckt (engl. committed). -Wenn sie geändert und in die Staging-Area hinzugefügt wurde, gilt sie als für den Commit vorgemerkt (engl. staged). -Und wenn sie geändert, aber noch nicht zur Staging-Area hinzugefügt wurde, gilt sie als geändert (engl. modified). -Im Kapitel <<_git_basics_chapter>> werden diese drei Zustände noch näher erläutert und wie man diese sinnvoll einsetzen kann oder alternativ, wie man den Zwischenschritt der Staging-Area überspringen kann. -======= -1. You modify files in your working tree. -2. You stage the files, adding snapshots of them to your staging area. -3. You do a commit, which takes the files as they are in the staging area and stores that snapshot permanently to your Git directory. - -If a particular version of a file is in the Git directory, it's considered committed. -If it has been modified and was added to the staging area, it is staged. -And if it was changed since it was checked out but has not been staged, it is modified. -In <<_git_basics_chapter>>, you'll learn more about these states and how you can either take advantage of them or skip the staged part entirely. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 diff --git a/book/01-introduction/sections/command-line.asc b/book/01-introduction/sections/command-line.asc index 9a96559c8..b69dcd9c4 100644 --- a/book/01-introduction/sections/command-line.asc +++ b/book/01-introduction/sections/command-line.asc @@ -1,4 +1,4 @@ -=== Kommandozeile +=== Die Kommandozeile Es gibt viele verschiedene Möglichkeiten Git einzusetzen. Auf der einen Seite gibt es die Werkzeuge, die per Kommandozeile bedient werden und auf der anderen, die vielen grafischen Benutzeroberflächen (engl. graphical user interface, GUI), die sich im Leistungsumfang unterscheiden. @@ -9,4 +9,3 @@ Außerdem ist die Wahl der grafischen Oberfläche eher Geschmackssache, wohingeg In diesem Buch gehen wir deshalb davon aus, dass Sie wissen, wie man bei einem Mac ein Terminal öffnet, oder wie man unter Windows die Eingabeaufforderung oder die Powershell öffnet. Sollten Sie jetzt nur Bahnhof verstehen, sollten Sie an dieser Stelle abbrechen und sich schlau machen, was ein Terminal bzw. Eingabeaufforderung ist und wie man diese bedient. Nur so ist sichergestellt, dass Sie unseren Beispielen und Ausführungen im weiteren Verlauf des Buches folgen können. - diff --git a/book/01-introduction/sections/first-time-setup.asc b/book/01-introduction/sections/first-time-setup.asc index 2b1228e44..212314f5d 100644 --- a/book/01-introduction/sections/first-time-setup.asc +++ b/book/01-introduction/sections/first-time-setup.asc @@ -1,41 +1,41 @@ [[_first_time]] === Git Basis-Konfiguration -Nachdem Git jetzt auf Ihrem System installiert ist, sollte Sie Ihre Git Konfiguration noch anpassen. +Nachdem Git jetzt auf Ihrem System installiert ist, sollten Sie Ihre Git Konfiguration noch anpassen. Dies muss nur einmalig auf dem jeweiligen System durchgeführt werden. Die Konfiguration bleibt bestehen, wenn Sie Git auf eine neuere Version aktualisieren. Die Git Konfiguration kann auch jederzeit geändert werden, indem die nachfolgenden Befehle einfach noch einmal ausgeführt werden. -Git umfasst das Werkzeug `git config`, welches die Möglichkeit bietet, Konfigurationswerte zu verändern. Auf diese Weise können Sie anpassen, wie Git aussieht und arbeitet.(((Git Befehle,config))) +Git umfasst das Werkzeug `git config`, welches die Möglichkeit bietet, Konfigurationswerte zu verändern. Auf diese Weise können Sie anpassen, wie Git aussieht und arbeitet.(((Git Befehle, config))) Die Konfiguration ist an drei verschiedenen Orten gespeichert: -1. Die Datei `/etc/gitconfig` enthält Parameter, die für jeden Anwender des Systems und alle Projekte gelten. - Wenn man `git config` mit der Option `--system` verwendet, wird von dieser Datei gelesen bzw. in diese Datei geschrieben. -2. Die Werte in der Datei `~/.gitconfig` gelten ausschließlich für den jeweiligen Benutzer. - Wenn man `git config` mit der Option `--global` verwendet, wird von dieser Datei gelesen bzw. in diese Datei geschrieben. -3. Die Datei `config` im Git Verzeichnis (also `.git/config) enthält Parameter, die für das jeweilige Projekt gelten. +1. Die Datei `/etc/gitconfig`: enthält Werte, die für jeden Benutzer auf dem System und alle seine Repositories gelten. + Wenn Sie die Option `--system` an `git config` übergeben, liest und schreibt sie spezifisch aus dieser Datei. + (Da es sich um eine Systemkonfigurationsdatei handelt, benötigen Sie Administrator- oder Superuser-Rechte, um Änderungen daran vorzunehmen.) +2. Die Datei `~/.gitconfig` oder `~/.config/git/config`: enthält Werte, die für Sie, den Benutzer, per­sönlich bestimmt sind. + Sie können Git dazu bringen, diese Datei gezielt zu lesen und zu schreiben, indem Sie die Option `--global` übergeben, und dies betrifft _alle_ der Repositories, mit denen Sie auf Ihrem System arbeiten. +3. Die Datei `config` im Git Verzeichnis (also `.git/config`) des jeweiligen Repositories, das Sie gerade verwenden: + Sie können Git mit der Option `--local` zwingen, aus dieser Datei zu lesen und in sie zu schreiben, das ist in der Regel die Standardoption. + (Es dürfte Sie nicht überraschen, dass Sie sich irgendwo in einem Git-Repository befinden müssen, damit diese Option ordnungsgemäß funktioniert.) -Diese drei Dateien haben unterschiedliche Prioritäten. Die oberste Priorität haben die Werte aus `.git/config`, dann folgt `~/.gitconfig` und zuletzt `/etc/gitconfig`. Ist zum Beispiel ein Parameter in `.git/config` und `/etc/gitconfig` mit unterschiedlichen Werten gesetzt, so gilt in diesem Fall der höherpriore Wert aus der Datei `.git/config`. + Jede Ebene überschreibt Werte der vorherigen Ebene, so dass Werte in `.git/config` diejenigen in `/etc/gitconfig` aushebeln. -<<<<<<< HEAD Auf Windows Systemen sucht Git nach der Datei `.gitconfig` im `$HOME` Verzeichnis (Normalerweise zeigt `$HOME` bei den meisten Systemen auf `C:\Users\$USER`). -Git schaut auch immer nach `/etc/gitconfig`, auch wenn dieses relativ zu dem MSys Wurzelverzeichnis ist, welches das ist, wohin man Git bei der Installation in Windows installiert hat. -======= -On Windows systems, Git looks for the `.gitconfig` file in the `$HOME` directory (`C:\Users\$USER` for most people). -It also still looks for `/etc/gitconfig`, although it's relative to the MSys root, which is wherever you decide to install Git on your Windows system when you run the installer. -If you are using version 2.x or later of Git for Windows, there is also a system-level config file at -`C:\Documents and Settings\All Users\Application Data\Git\config` on Windows XP, and in `C:\ProgramData\Git\config` on Windows Vista and newer. -This config file can only be changed by `git config -f ` as an admin. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Git schaut immer nach `/etc/gitconfig`, auch wenn die sich relativ zu dem MSys-Wurzelverzeichnis befindet, dem Verzeichnis in das Sie Git installiert haben. +Wenn Sie eine Version 2.x oder neuer von Git für Windows verwenden, gibt es auch eine Konfigurationsdatei auf Systemebene unter +`C:\Dokumente und Einstellungen\Alle Benutzer\Anwendungsdaten\Git\config` unter Windows XP und unter `C:\ProgramData\Git\config` unter Windows Vista und neuer. +Diese Konfigurationsdatei kann nur von `git config -f ` als Admin geändert werden. + +Sie können sich alle Ihre Einstellungen ansehen sehen, wo sie herkommen: + +[source,console] +---- +$ git config --list --show-origin +---- ==== Ihre Identität -<<<<<<< HEAD Nachdem Sie Git installiert haben, sollten Sie als aller erstes Ihren Namen und E-Mail Adresse in Git konfigurieren. -Das ist wichtig, weil Git diese Information für jeden Commit, der von Ihnen angelegt wird, hinterlegt. Diese Daten sind unveränderlich mit in Ihren erstellten Commits integriert: -======= -The first thing you should do when you install Git is to set your user name and email address. -This is important because every Git commit uses this information, and it's immutably baked into the commits you start creating: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Das ist insofern wichtig,da jeder Git-Commit diese Informationen verwendet und sie unveränderlich in die Commits eingearbeitet werden, die Sie erstellen: [source,console] ---- @@ -43,65 +43,51 @@ $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com ---- -<<<<<<< HEAD -Wie schon erwähnt, brauchen Sie diese Konfiguration nur einmal vorzunehmen, wenn Sie die Option `--global` verwenden. Auf Grund der oben erwähnten Prioritäten gilt diese dann für all Ihre Projekte. +Wie schon erwähnt, brauchen Sie diese Konfiguration nur einmal vorzunehmen, wenn Sie die Option `--global` verwenden. Auf Grund der oben erwähnten Prioritäten gilt das dann für alle Ihre Projekte. Wenn Sie für ein spezielles Projekt einen anderen Namen oder eine andere E-Mail Adresse verwenden möchten, können Sie den Befehl ohne die `--global` Option innerhalb des Projektes ausführen. -======= -Again, you need to do this only once if you pass the `--global` option, because then Git will always use that information for anything you do on that system. -If you want to override this with a different name or email address for specific projects, you can run the command without the `--global` option when you're in that project. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 -Viele der grafischen Oberflächen helfen einem bei diesem Schritt, wenn man sie zum allerersten mal startet. +Viele der grafischen Oberflächen helfen einem bei diesem Schritt, wenn Sie sie zum ersten Mal ausführen. -==== Texteditor +[[_editor]] +==== Ihr Editor -<<<<<<< HEAD -Nachdem Sie Ihre Identität konfiguriert haben, können Sie als nächstes einstellen, welchen Texteditor Git in Situationen verwenden soll, in denen Sie einen Text oder Nachricht eingeben müssen. Normalerweise verwendet Git den Standard-Texteditor des jeweiligen Systems – das ist üblicherweise Vim. Wenn Sie einen anderen Texteditor, z.B. Emacs, verwenden wollen, können Sie das wie folgt festlegen: -======= -Now that your identity is set up, you can configure the default text editor that will be used when Git needs you to type in a message. -If not configured, Git uses your system's default editor. +Jetzt, da Ihre Identität eingerichtet ist, können Sie den Standard-Texteditor konfigurieren, der verwendet wird, wenn Git Sie zum Eingeben einer Nachricht auffordert. +Normalerweise verwendet Git den Standard-Texteditor des jeweiligen Systems. -If you want to use a different text editor, such as Emacs, you can do the following: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Wenn Sie einen anderen Texteditor, z.B. Emacs, verwenden wollen, können Sie das wie folgt festlegen: [source,console] ---- $ git config --global core.editor emacs ---- -While on a Windows system, if you want to use a different text editor, such as Notepad++, you can do the following: +Wenn Sie auf einem Windows-System einen anderen Texteditor verwenden möchten, müssen Sie den vollständigen Pfad zu seiner ausführbaren Datei angeben. +Dies kann, je nachdem, wie Ihr Editor eingebunden ist, unterschiedlich sein. + +Im Falle von Notepad++, einem beliebten Programmiereditor, sollten Sie wahrscheinlich die 32-Bit-Version verwenden, da die 64-Bit-Version zum Zeitpunkt der Erstellung nicht alle Plug-Ins unterstützt. +Beim Einsatz auf einem 32-Bit-Windows-System oder einem 64-Bit-Editor auf einem 64-Bit-System geben Sie etwa Folgendes ein: -On a x86 system -[source,console] ----- -$ git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -nosession" ----- -On a x64 system [source,console] ---- -$ git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -nosession" +$ git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin" ---- [NOTE] ==== -Vim, Emacs and Notepad++ are popular text editors often used by developers on Unix based systems like Linux and OS X or a Windows system. -If you are not familiar with either of these editors, you may need to search for specific instructions for how to set up your favorite editor with Git. +Vim, Emacs und Notepad++ sind beliebte Texteditoren, die von Entwicklern häufig auf Unix-basierten Systemen wie Linux und MacOS oder einem Windows-System verwendet werden. +Wenn Sie einen anderen Editor oder eine 32-Bit-Version verwenden, finden Sie in <> spezielle Anweisungen, wie Sie Ihren bevorzugten Editor mit Git einrichten können. + ==== [WARNING] ==== -<<<<<<< HEAD -Auf Unix basierten Betriebssystemen, wie Linux und Mac, verwenden Entwickler häufig die weit verbreiteten Texteditoren Vim und Emacs. Wenn Sie sich in beiden Editoren nicht auskennen oder mit einem Windowssystem arbeiten, müssen Sie vielleicht ein wenig suchen, wie man Ihren favorisierten Texteditor für Git konfiguriert. Im Internet oder in der Hilfe Ihres Editors finden Sie bestimmt eine Hilfestellung. Wenn Sie Git nicht so konfigurieren, dass es Ihren Texteditor verwendet und Sie keine Ahnung davon haben, wie man Vim oder Emacs benutzt, werden Sie ein wenig überfordert sein, wenn diese zum ersten Mal von Git gestartet werden. -======= -You may find, if you don't setup an editor like this, you will likely get into a really confusing state when they are launched. -Such example on a Windows system may include a prematurely terminated Git operation during a Git initiated edit. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Ein Beispiel: auf einem Windows-System kann es eine vorzeitig beendete Git-Operation während einer von Git angestoßenen Verarbeitung sein. ==== ==== Einstellungen überprüfen -Wenn Sie Ihre persönlichen Einstellungen überprüfen wollen, können Sie mit dem Befehl `git config --list` alle Einstellungen anzeigen lassen, die Git an dieser Stelle (z.B. innerhalb eines bestimmten Projektes) bekannt sind: +Wenn Sie Ihre Konfigurationseinstellungen überprüfen möchten, können Sie mit dem Befehl `git config --list` alle Einstellungen auflisten, die Git derzeit finden kann: [source,console] ---- @@ -125,3 +111,15 @@ Außerdem können Sie mit dem Befehl `git config ` prüfen, welchen Wert Gi $ git config user.name John Doe ---- + +[NOTE] +==== +Da Git möglicherweise den gleichen Wert der Konfigurationsvariablen aus mehr als einer Datei liest, ist es möglich, dass Sie einen unerwarteten Wert für einen dieser Werte haben und nicht wissen, warum. +In solchen Fällen können Sie Git nach dem _Ursprung (origin)_ für diesen Wert fragen, und es wird Ihnen sagen, mit welcher Konfigurationsdatei der Wert letztendlich festgelegt wurde: + +[source,console] +---- +$ git config --show-origin rerere.autoUpdate +file:/home/johndoe/.gitconfig false +---- +==== diff --git a/book/01-introduction/sections/help.asc b/book/01-introduction/sections/help.asc index 30c38bc1d..f63a97fe3 100644 --- a/book/01-introduction/sections/help.asc +++ b/book/01-introduction/sections/help.asc @@ -18,5 +18,30 @@ $ git help config ---- Diese Befehle sind nützlich, weil Sie sich die Hilfe jederzeit anzeigen lassen können, auch wenn Sie einmal offline sind. -Wenn die Hilfeseiten und dieses Buch nicht die gesuchten Antworten bringen, können Sie Ihr Glück in den Räumen `#git` oder `#github` auf dem Freenode IRC Server (irc.freenode.net) versuchen. -Diese Räume sind in der Regel sehr gut besucht. Normalerweise findet sich unter den vielen Anwendern, die oft sehr viel Erfahrung mit Git haben, irgendjemand, der Ihnen weiterhelfen kann.(((IRC))) +Wenn die Hilfeseiten und dieses Buch nicht ausreichen und Sie persönliche Hilfe brauchen, können Sie den `#git` oder `#github` Kanal auf dem Freenode IRC Server probieren, der unter https://freenode.net zu finden ist. +Diese Kanäle sind in der Regel sehr gut besucht. Normalerweise findet sich unter den vielen Anwendern, die oft sehr viel Erfahrung mit Git haben, irgendjemand, der Ihnen weiterhelfen kann.(((IRC))) + +Wenn Sie nicht die vollständige Manpage-Hilfe benötigen, sondern nur eine kurze Beschreibung der verfügbaren Optionen für einen Git-Befehl, können Sie auch in den kompakteren „Hilfeseiten“ mit den Optionen `-h` oder `--help` nachschauen, wie in: + +[source,console] +---- +$ git add -h +usage: git add [] [--] ... + + -n, --dry-run dry run + -v, --verbose be verbose + + -i, --interactive interactive picking + -p, --patch select hunks interactively + -e, --edit edit current diff and apply + -f, --force allow adding otherwise ignored files + -u, --update update tracked files + --renormalize renormalize EOL of tracked files (implies -u) + -N, --intent-to-add record only the fact that the path will be added later + -A, --all add changes from all tracked and untracked files + --ignore-removal ignore paths removed in the working tree (same as --no-all) + --refresh don't add, only refresh the index + --ignore-errors just skip files which cannot be added because of errors + --ignore-missing check if - even missing - files are ignored in dry run + --chmod (+|-)x override the executable bit of the listed files +---- diff --git a/book/01-introduction/sections/history.asc b/book/01-introduction/sections/history.asc index c38c92a63..1cc6f2937 100644 --- a/book/01-introduction/sections/history.asc +++ b/book/01-introduction/sections/history.asc @@ -15,5 +15,5 @@ Die Ziele des neuen Systems waren unter anderem: * Vollständig dezentrale Struktur * Fähigkeit große Projekte, wie den Linux Kernel, effektiv zu verwalten (Geschwindigkeit und Datenumfang) -Seit seiner Geburt 2005, entwickelte sich Git kontinuierlich weiter und reifte zu einem System heran, das einfach zu bedienen ist, die ursprünglichen Ziele dabei aber weiter beibehält. -Es ist unglaublich schnell, äußerst effizient, wenn es um große Projekte geht, und es hat ein fantastisches Branching Konzept für nicht-lineare Entwicklung (siehe <<_git_branching>>). +Seit seiner Geburt 2005, entwickelte sich Git kontinuierlich weiter und reifte zu einem System heran, das einfach zu bedienen ist, die ursprünglichen Ziele dabei aber weiter beibehält. +Es ist unglaublich schnell, äußerst effizient, wenn es um große Projekte geht, und es hat ein fantastisches Branching Konzept für nicht-lineare Entwicklung (siehe Kapitel 3 <>). diff --git a/book/01-introduction/sections/installing.asc b/book/01-introduction/sections/installing.asc index bb9f867ee..412195a43 100644 --- a/book/01-introduction/sections/installing.asc +++ b/book/01-introduction/sections/installing.asc @@ -1,147 +1,127 @@ === Git installieren -Bevor man mit Git loslegen kann, muss man es natürlich als aller erstes installieren. -Auch wenn es vielleicht bereits auf dem Rechner installiert ist, sollte man sicherstellen, dass die aktuellste Version vorhanden ist. -Es gibt verschiedene Möglichkeiten Git zu installieren. Man kann es entweder als fertiges Paket oder über ein Installationsprogramm installieren, oder alternativ den Quellcode herunterladen und selbst kompilieren. +Bevor Sie mit Git loslegen können, muss es natürlich zuerst installiert werden. +Auch wenn es bereits vorhanden ist, ist es vermutlich eine gute Idee, auf die neueste Version zu aktualisieren. +Sie können es entweder als Paket oder über ein anderes Installationsprogramm installieren oder den Quellcode herunterladen und selbst kompilieren. [NOTE] ==== -<<<<<<< HEAD -Die Beispiele aus diesem Buch basieren alle auf Git in der Version *2.0.0*. Auch wenn die meisten Befehle, die wir anwenden werden, auch in älteren Versionen funktionieren, kann es doch sein, dass die Befehlsausgabe oder das Verhalten leicht anders ist. Da in Git sehr auf Abwärtskompatibilität geachtet wird, sollten aber alle neueren Versionen nach der Version 2.0 genauso gut funktionieren. -======= -This book was written using Git version *2.0.0*. -Though most of the commands we use should work even in ancient versions of Git, some of them might not or might act slightly differently if you're using an older version. -Since Git is quite excellent at preserving backwards compatibility, any version after 2.0 should work just fine. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Dieses Buch wurde auf Basis der Git Version *2.8.0* geschrieben. +Auch wenn die meisten Befehle, die wir anwenden werden, auch in älteren Versionen funktionieren, kann es doch sein, dass die Befehlsausgabe oder das Verhalten leicht anders ist. +Da in Git sehr auf Abwärtskompatibilität geachtet wird, sollten aber alle neueren Versionen nach der Version 2.0 genauso gut funktionieren. ==== ==== Installation unter Linux -<<<<<<< HEAD -(((Linux, Installation))) -Wenn man Git unter Linux mit einem Installationsprogramm installieren will, kann man das normalerweise mit dem Paketmanager, der jeweiligen Distribution tun. -Unter Fedora zum Beispiel, kann man dazu yum verwenden: -======= (((Linux, installing))) -If you want to install the basic Git tools on Linux via a binary installer, you can generally do so through the basic package-management tool that comes with your distribution. -If you're on Fedora for example, you can use yum: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Wenn Sie die grundlegenden Git-Tools unter Linux über ein Installationsprogramm installieren möchten, können Sie das in der Regel über das Paketverwaltungstool der Distribution tun. +Wenn Sie mit Fedora (oder einer anderen eng damit verbundenen RPM-basierten Distribution, wie RHEL oder CentOS) arbeiten, können Sie `dnf` verwenden: [source,console] ---- -$ sudo yum install git-all +$ sudo dnf install git-all ---- -Auf einem Debian-basierten System, wie Ubuntu, steht apt-get zur Verfügung: +Auf einem Debian-basierten System, wie Ubuntu, steht `apt` zur Verfügung: [source,console] ---- -$ sudo apt-get install git-all +$ sudo apt install git-all ---- Auf der Git Homepage http://git-scm.com/download/linux[] findet man weitere Möglichkeiten und Optionen, wie man Git unter einem Unix-basierten Betriebssystem installieren kann. -==== Installation unter Mac OS X +==== Installation unter macOS -(((Mac, Installation))) -Auch beim Mac gibt es verschiedene Wege um Git zu installieren. -Der einfachste ist wahrscheinlich, die Xcode Kommandozeilenwerkzeuge zu installieren.(((Xcode))) +(((macOS, installing))) +Es gibt mehrere Möglichkeiten, Git auf einem Mac zu installieren. +Am einfachsten ist es wahrscheinlich, die Xcode Command Line Tools zu installieren.(((Xcode))) Bei Mavericks (10.9) oder neueren Versionen kann man dazu einfach 'git' im Terminal eingeben. + +[source,console] +---- +$ git --version +---- + Wenn Git noch nicht installiert ist, erscheint eine Abfrage, ob man es installieren möchte. Wenn man eine sehr aktuelle Version einsetzen möchte, kann man Git auch über ein Installationsprogramm installieren. -Auf der Git Homepage http://git-scm.com/download/mac[] findet man die jeweils aktuellste Version und kann sie von dort herunterladen. +Auf der Git Website http://git-scm.com/download/mac[] findet man die jeweils aktuellste Version und kann sie von dort herunterladen.. -.Git OS X Installationsprogramm. -image::images/git-osx-installer.png[Git OS X installer.] +.Git macOS Installationsprogramm. +image::images/git-osx-installer.png[Git macOS installer.] -Ein weitere Möglichkeit ist es, GitHub for Mac zu installieren. +Ein weitere Möglichkeit ist „GitHub for Mac“ zu installieren. Es gibt dort eine Option, dass man neben der grafischen Oberfläche auch gleich die Kommandozeilen Werkzeuge mit installieren kann. -GitHub for Mac kann man unter http://mac.github.com[] herunterladen. +„GitHub for Mac“ kann man unter http://mac.github.com[] herunterladen. ==== Installation unter Windows -<<<<<<< HEAD -(((Windows, Installation))) -Auch für Windows gibt es einige, wenige Möglichkeiten zur Installation von Git. +Auch für Windows gibt es einige, wenige Möglichkeiten zur Installation von Git.(((Windows, installing))) Eine offizielle Windows Version findet man direkt auf der Git Homepage. Gehen Sie dazu auf http://git-scm.com/download/win[] und der Download sollte dann automatisch starten. -Man sollte dabei beachten, dass es sich hierbei um das Projekt Git for Windows handelt (auch msysGit genannt), welches unabhängig von Git selbst ist. Weitere Informationen hierzu finden Sie unter http://msysgit.github.io/[]. -======= -There are also a few ways to install Git on Windows.(((Windows, installing))) -The most official build is available for download on the Git website. -Just go to http://git-scm.com/download/win[] and the download will start automatically. -Note that this is a project called Git for Windows, which is separate from Git itself; for more information on it, go to https://git-for-windows.github.io/[]. - -To get an automated installation you can use the https://chocolatey.org/packages/git[Git Chocolatey package]. -Note that the Chocolatey package is community maintained. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 - -Eine weitere Möglichkeit ist es, GitHub for Windows zu installieren. +Man sollte dabei beachten, dass es sich hierbei um das Projekt Git for Windows handelt, welches unabhängig von Git selbst ist. Weitere Informationen hierzu finden Sie unter http://msysgit.github.io/[]. + +Um eine automatisierte Installation zu erhalten, können Sie das https://chocolatey.org/packages/git[Git Chocolatey Paket] verwenden. +Beachten Sie, dass das Chocolatey-Paket von der Community gepflegt wird. + +Eine weitere einfache Möglichkeit, Git zu installieren, ist die Installation von GitHub Desktop. Das Installationsprogramm enthält neben der GUI, auch eine Kommandozeilenversion von Git. -Diese funktioniert zusammen mit der Powershell tadellos, und richtet die wichtigsten Berechtigungs-Caching- (engl. credential caching) und Zeilenenden-Konfigurationen (CRLF) vorab ein.(((Powershell)))(((CRLF)))(((Berechtigungs-Caching))) -Was es damit genau auf sich hat, werden Sie erst später verstehen. Erst mal reicht es aus, dass Sie wissen, dass sie so etwas haben wollen. -Sie können das ganze Paket von der GitHub for Windows Homepage unter http://windows.github.com[] herunterladen. +Diese funktioniert zusammen mit der Powershell tadellos, und richtet die wichtigsten Berechtigungs-Caching (engl. credential caching) und Zeilenenden-Konfigurationen (CRLF) vorab ein.(((Powershell)))(((CRLF)))(((Berechtigungs-Caching))) +Wir werden später etwas mehr darüber erfahren, jetzt reicht es festzustellen, dass es sich um die wünschenswerte Funktionen handelt. +Sie können das ganze „GitHub for Windows“ Paket von der https://desktop.github.com[GitHub Desktop Website] herunterladen. -<<<<<<< HEAD -==== Vom Quellcode aus installieren +==== Aus dem Quellcode installieren Viele Leute kompilieren Git auch auf ihrem eigenen Rechner, weil sie damit, die jeweils aktuellste Version erhalten. Die vorbereiteten Pakete hinken meist ein wenig hinterher. Heutzutage ist dies nicht mehr ganz so schlimm, da Git einen gewissen Reifegrad erfahren hat. -Um Git zu installieren, benötigt man die folgenden Bibliotheken, die von Git verwendet werden: curl, zlib, openssl, expat und libiconv. -Wenn auf dem System yum (z.B. auf Fedora) oder apt-get (z.B auf allen Debian-basierten System) zur Verfügung steht, kann man folgende Befehle verwenden, um diese Abhängigkeiten zu installieren: -======= -==== Installing from Source - -Some people may instead find it useful to install Git from source, because you'll get the most recent version. -The binary installers tend to be a bit behind, though as Git has matured in recent years, this has made less of a difference. - -If you do want to install Git from source, you need to have the following libraries that Git depends on: autotools, curl, zlib, openssl, expat, and libiconv. -For example, if you're on a system that has yum (such as Fedora) or apt-get (such as a Debian based system), you can use one of these commands to install the minimal dependencies for compiling and installing the Git binaries: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Wenn Sie Git aus dem Quellcode installieren möchten, benötigen Sie die folgenden Bibliotheken, von denen Git abhängt: autotools, curl, zlib, openssl, expat und libiconv. +Wenn Sie sich beispielsweise auf einem System befinden, das Paketverwaltungen, wie `dnf` (Fedora) oder `apt-get` (ein Debian-basiertes System) hat, können Sie mit einem dieser Befehle die minimalen Abhängigkeiten für die Kompilierung und Installation der Git-Binärdateien installieren: [source,console] ---- -$ sudo yum install dh-autoreconf curl-devel expat-devel gettext-devel \ +$ sudo dnf install dh-autoreconf curl-devel expat-devel gettext-devel \ openssl-devel perl-devel zlib-devel $ sudo apt-get install dh-autoreconf libcurl4-gnutls-dev libexpat1-dev \ gettext libz-dev libssl-dev ---- -In order to be able to add the documentation in various formats (doc, html, info), these additional dependencies are required (Note: users of RHEL and RHEL-derivatives like CentOS and Scientific Linux will have to https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F[enable the EPEL repository] to download the `docbook2X` package): +Um die Dokumentation in verschiedenen Formaten (doc, html, info) zu erstellen, sind weitere Abhängigkeiten notwendig (Hinweis: Benutzer von RHEL und RHEL-Derivaten wie CentOS und Scientific Linux müssen das https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F[EPEL-Repository aktivieren], um das Paket `docbook2X` herunterzuladen): [source,console] ---- -$ sudo yum install asciidoc xmlto docbook2X +$ sudo dnf install asciidoc xmlto docbook2X $ sudo apt-get install asciidoc xmlto docbook2x ---- -<<<<<<< HEAD -Um die Dokumentation in verschiedenen Formaten (doc, html, info) zu erstellen, sind weitere Abhängigkeiten notwendig: -======= -Additionally, if you're using Fedora/RHEL/RHEL-derivatives, you need to do this ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Wenn Sie eine Debian-basierte Distribution (Debian, Ubuntu oder deren Derivate) verwenden, benötigen Sie auch das Paket `install-info`: [source,console] ---- -$ sudo ln -s /usr/bin/db2x_docbook2texi /usr/bin/docbook2x-texi +$ sudo apt-get install install-info ---- -due to binary name differences. +Wenn Sie eine RPM-basierte Distribution (Fedora, RHEL oder deren Derivate) verwenden, benötigen Sie auch das Paket `getopt` (welches auf einer Debian-basierten Distribution bereits installiert ist): -<<<<<<< HEAD -Wenn man alle notwendigen Abhängigkeiten installiert hat, kann man sich als nächstes die jeweils aktuellste Version als Tarball von verschiedenen Stellen herunterladen. +[source,console] +---- +$ sudo dnf install getopt +$ sudo apt-get install getopt +---- + +Wenn Sie Fedora- oder RHEL-Derivate verwenden, müssen Sie wegen der unterschiedlichen Paketnamen zusätzlich einen Symlink erstellen indem Sie folgenden Befehl ausführen: + +[source,console] +---- +$ sudo ln -s /usr/bin/db2x_docbook2texi /usr/bin/docbook2x-texi +---- -Man findet die Quellen auf der Kernel.org Website unter https://www.kernel.org/pub/software/scm/git[], oder gespiegelt auf der GitHub Website unter https://github.com/git/git/releases[]. -Auf der GitHub Homepage ist es einfacher herauszufinden, welches die jeweils aktuellste Version ist. Auf kernel.org hingegen werden auch Signaturen, zur Verifikation des Downloads, der jeweiligen Pakete zur Verfügung gestellt. -======= -When you have all the necessary dependencies, you can go ahead and grab the latest tagged release tarball from several places. -You can get it via the Kernel.org site, at https://www.kernel.org/pub/software/scm/git[], or the mirror on the GitHub website, at https://github.com/git/git/releases[]. -It's generally a little clearer what the latest version is on the GitHub page, but the kernel.org page also has release signatures if you want to verify your download. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Wenn Sie alle notwendigen Abhängigkeiten installiert haben, können Sie sich als nächstes die jeweils aktuellste Version als Tarball von verschiedenen Stellen herunterladen. +Man findet die Quellen auf der Kernel.org Website unter https://www.kernel.org/pub/software/scm/git[], oder einen Mirror auf der GitHub Website unter https://github.com/git/git/releases[]. +Auf der GitHub Seite ist es einfacher herauszufinden, welches die jeweils aktuellste Version ist. Auf kernel.org dagegen werden auch Signaturen, zur Verifikation des Downloads, der jeweiligen Pakete zur Verfügung gestellt. -Nachdem man sich die Quellen also beschafft hat, kann man Git kompilieren und installieren: +Nachdem man sich so die Quellen beschafft hat, kann man Git kompilieren und installieren: [source,console] ---- @@ -155,11 +135,7 @@ $ sudo make install install-doc install-html install-info Jetzt nachdem Git installiert ist, kann man sich Git Updates auch per Git beschaffen: -<<<<<<< HEAD - $ git Uclone git://git.kernel.org/pub/scm/git/git.git -======= [source,console] ---- $ git clone git://git.kernel.org/pub/scm/git/git.git ---- ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 diff --git a/book/01-introduction/sections/what-is-git.asc b/book/01-introduction/sections/what-is-git.asc new file mode 100644 index 000000000..8ab4deaa8 --- /dev/null +++ b/book/01-introduction/sections/what-is-git.asc @@ -0,0 +1,107 @@ +=== Was ist Git? + +Also, was ist Git in Kürze? +Das ist ein wichtiger Teil, den es zu beachten gilt, denn wenn Sie verstehen, was Git und das grundlegenden Konzept seiner Arbeitsweise ist, dann wird die effektive Nutzung von Git für Sie wahrscheinlich viel einfacher sein. +Wenn Sie Git erlernen, versuchen Sie, Ihren Kopf von den Dingen zu befreien, die Sie über andere VCSs wissen, wie CVS, Subversion oder Perforce – das wird Ihnen helfen, unangenehme Missverständnisse bei der Verwendung des Tools zu vermeiden. +Auch wenn die Benutzeroberfläche von Git diesen anderen VCSs sehr ähnlich ist, speichert und betrachtet Git Informationen auf eine ganz andere Weise, und das Verständnis dieser Unterschiede hilft Ihnen Unklarheiten bei der Verwendung zu vermeiden.(((Subversion)))(((Perforce))) + +==== Snapshots und nicht die Unterschiedes + +Der Hauptunterschied zwischen Git und anderen Versionsverwaltungssystemen (insbesondere auch Subversion und vergleichbare Systeme) besteht in der Art und Weise wie Git die Daten betrachtet. +Konzeptionell speichern die meisten anderen Systeme Informationen als eine Liste von dateibasierten Änderungen. +Diese Systeme (CVS, Subversion, Perforce, Bazaar usw.) betrachten die Informationen, die sie verwalten, als eine Reihe von Dateien an denen im Laufe der Zeit Änderungen vorgenommen werden (dies wird allgemein als deltabasierte Versionskontrolle bezeichnet). + +.Speichern von Daten als Änderung an einzelnen Dateien auf Basis einer Ursprungsdatei. +image::images/deltas.png[Storing data as changes to a base version of each file.] + +Git arbeitet nicht auf diese Art und Weise. +Stattdessen betrachtet Git seine Daten eher wie eine Reihe von Schnappschüssen eines Mini-Dateisystems. +Git macht jedes Mal, wenn Sie den Status Ihres Projekts committen, das heißt den gegenwärtigen Status Ihres Projekts als eine Version in Git speichern, ein Abbild von all Ihren Dateien wie sie gerade aussehen und speichert einen Verweis in diesem Schnappschuss. +Um dies möglichst effizient und schnell tun zu können, kopiert Git unveränderte Dateien nicht, sondern legt lediglich eine Verknüpfung zu der vorherigen Version der Datei an. +Git betrachtet seine Daten eher wie einen *Stapel von Schnappschüssen*. + +.Speichern der Daten-Historie eines Projekts in Form von Schnappschüssen. +image::images/snapshots.png[Git stores data as snapshots of the project over time.] + +Das ist ein wichtiger Unterschied zwischen Git und praktisch allen anderen Versionsverwaltungssystemen. +In Git wurden daher fast alle Aspekte der Versionsverwaltung neu überdacht, die in anderen Systemen mehr oder weniger von ihrer jeweiligen Vorgängergeneration übernommen worden waren. +Git arbeitet im Großen und Ganzen eher wie ein mit einigen unglaublich mächtigen Werkzeugen ausgerüstetes Mini-Dateisystem, statt nur als Versionsverwaltungssystem. Auf einige der Vorteile, die es mit sich bringt, Daten in dieser Weise zu verwalten, werden wir in Kapitel 3, <>, eingehen, wenn wir das Git Branching Konzept kennenlernen. + +==== Fast jede Funktion arbeitet lokal + +Die meisten Aktionen in Git benötigen nur lokale Dateien und Ressourcen, um ausgeführt zu werden – im Allgemeinen werden keine Informationen von einem anderen Computer in Ihrem Netzwerk benötigt. +Wenn Sie an ein CVCS gewöhnt sind, in dem die meisten Operationen diesen Netzwerk-Latenz-Overhead haben, wird Sie dieser Aspekt von Git denken lassen, dass die Götter der Geschwindigkeit Git mit außerirdischen Kräften gesegnet haben. +Die allermeisten Operationen können nahezu ohne jede Verzögerung ausgeführt werden, da die vollständige Historie eines Projekts bereits auf dem jeweiligen Rechner verfügbar ist. + +Um beispielsweise die Historie des Projekts zu durchsuchen, braucht Git sie nicht von einem externen Server zu holen – es liest diese einfach aus der lokalen Datenbank. +Das heißt, die vollständige Projekthistorie ist ohne jede Verzögerung verfügbar. +Wenn man sich die Änderungen einer aktuellen Version einer Datei im Vergleich zu vor einem Monat, anschauen möchte, dann kann Git den Stand von vor einem Monat in der lokalen Historie nachschlagen und einen lokalen Vergleich zur vorliegenden Datei durchführen. Für diesen Anwendungsfall benötigt Git keinen externen Server, weder um Dateien dort nachzuschlagen, noch um Unterschiede dort bestimmen zu lassen. + +Das bedeutet natürlich außerdem, dass es fast nichts gibt, was man nicht tun kann, nur weil man gerade offline ist oder keinen Zugriff auf ein VPN hat. +Wenn man also gerade im Flugzeug oder Zug ein wenig arbeiten will, kann man problemlos seine Arbeit einchecken und dann wenn man wieder mit einem Netzwerk verbunden ist, die Dateien auf einen Server hochladen. +Wenn man zu Hause sitzt, aber der VPN Client gerade mal wieder nicht funktioniert, kann man immer noch arbeiten. +Bei vielen anderen Systemen wäre dies unmöglich oder äußerst kompliziert umzusetzen. +In Perforce können Sie beispielsweise nicht viel tun, wenn Sie nicht mit dem Server verbunden sind; in Subversion und CVS können Sie Dateien bearbeiten, aber Sie können keine Änderungen zu Ihren Daten übertragen (weil die Datenbank offline ist). +Das scheint keine große Sache zu sein, aber Sie werden überrascht sein, was für einen großen Unterschied es machen kann. + +==== Git stellt Integrität sicher + +Von allen zu speichernden Daten berechnet Git Prüfsummen (engl. checksum) und speichert diese als Referenz zusammen mit den Daten ab. +Das macht es unmöglich, dass sich Inhalte von Dateien oder Verzeichnissen ändern, ohne dass Git das mitbekommt. +Git basiert auf dieser Funktionalität und sie ist ein integraler Teil der Git Philosophie. +Man kann Informationen deshalb z.B. nicht während der Übermittlung verlieren oder unwissentlich beschädigte Dateien verwenden, ohne dass Git in der Lage wäre, dies festzustellen. + +Der Mechanismus, den Git verwendet, um diese Prüfsummen zu erstellen, heißt SHA-1 Hash.(((SHA-1))) +Eine solche Prüfsumme ist eine 40 Zeichen lange Zeichenkette, die aus hexadezimalen Zeichen (0-9 und a-f) besteht und wird von Git aus den Inhalten einer Datei oder Verzeichnisstruktur berechnet. +Ein SHA-1 Hash sieht wie folgt aus: + +[source] +---- +24b9da6552252987aa493b52f8696cd6d3b00373 +---- + +Diese Hashes begegnen einem überall bei der Arbeit, weil sie so ausgiebig von Git genutzt werden. +Tatsächlich speichert Git alles in seiner Datenbank nicht nach Dateinamen, sondern nach dem Hash-Wert seines Inhalts. + +==== Git fügt im Regelfall nur Daten hinzu + +Wenn Sie Aktionen in Git durchführen, werden fast alle von ihnen nur Daten zur Git-Datenbank _hinzufügen_. +Deshalb ist es sehr schwer, das System dazu zu bewegen, irgendetwas zu tun, das nicht wieder rückgängig zu machen ist, oder dazu, Daten in irgendeiner Form zu löschen. +Wie in jedem anderen VCS, kann man in Git Daten verlieren oder durcheinander bringen, solange man sie noch nicht eingecheckt hat. Aber sobald man einen Schnappschuss in Git eingecheckt hat, ist es sehr schwierig, diese Daten wieder zu verlieren, insbesondere wenn man regelmäßig seine lokale Datenbank auf ein anderes Repository hochlädt. + +Unter anderem deshalb macht es so viel Spaß mit Git zu arbeiten. Man weiß genau, man kann ein wenig experimentieren, ohne befürchten zu müssen, irgendetwas zu zerstören oder durcheinander zu bringen. +Wer sich genauer dafür interessiert, wie Git Daten speichert und wie man Daten, die scheinbar verloren sind, wiederherstellen kann, dem wird das Kapitel 2, <>, ans Herz gelegt.. + +==== Die drei Zustände + +Jetzt heißt es aufgepasst! – Es folgt die wichtigste Information, die man sich merken muss, wenn man Git erlernen und dabei Fallstricke vermeiden will. +Git definiert drei Hauptzustände, in denen sich eine Datei befinden kann: committet (engl. _committed_), geändert (engl. _modified_) und für Commit vorgemerkt (engl. _staged_). + +* *Modified* bedeutet, dass eine Datei geändert, aber noch nicht in die lokale Datenbank eingecheckt wurde. +* *Staged* bedeutet, dass eine geänderte Datei in ihrem gegenwärtigen Zustand für den nächsten Commit vorgemerkt ist. +* *Committed* bedeutet, dass die Daten sicher in der lokalen Datenbank gespeichert sind. + +Das führt uns zu den drei Hauptbereichen eines Git-Projekts: dem Verzeichnisbaum, der sogenannten Staging-Area und dem Git-Verzeichnis. + +.Verzeichnisbaum, Staging-Area und Git-Verzeichnis. +image::images/areas.png["Working tree, staging area, and Git directory."] + +Der Verzeichnisbaum ist ein einzelner Abschnitt einer Version des Projekts. +Diese Dateien werden aus der komprimierten Datenbank im Git-Verzeichnis geholt und auf der Festplatte so abgelegt, damit Sie sie verwenden oder ändern können. + +Die Staging-Area ist in der Regel eine Datei, die sich in Ihrem Git-Verzeichnis befindet und Informationen darüber speichert, was in Ihren nächsten Commit einfließen soll. +Der technische Name im Git-Sprachgebrauch ist „Index“, aber der Ausdruck „Staging Area“ funktioniert genauso gut. + +Im Git-Verzeichnis werden die Metadaten und die Objektdatenbank für Ihr Projekt gespeichert. +Das ist der wichtigste Teil von Git, dieser Teil wird kopiert, wenn man ein Repository von einem anderen Rechner _klont_. + +Der grundlegende Git-Arbeitsablauf sieht in etwa so aus: + +1. Sie ändern Dateien in Ihrem Verzeichnisbaum. +2. Sie stellen selektiv Änderungen bereit, die Sie bei Ihrem nächsten Commit berücksichtigen möchten, wodurch nur diese Änderungen in den Staging-Bereich aufgenommen werden. +3. Sie führen einen Commit aus, der die Dateien so übernimmt, wie sie sich in der Staging-Area befinden und diesen Snapshot dauerhaft in Ihrem Git-Verzeichnis speichert. + +Wenn sich eine bestimmte Version einer Datei im Git-Verzeichnis befindet, wird sie als _committed_ betrachtet. +Wenn sie geändert und in die Staging-Area hinzugefügt wurde, gilt sie als für den Commit _vorgemerkt_ (engl. _staged_). +Und wenn sie geändert, aber noch nicht zur Staging-Area hinzugefügt wurde, gilt sie als _geändert_ (engl. _modified_). +Im Kapitel 2, <>, werden diese drei Zustände noch näher erläutert und wie man diese sinnvoll einsetzen kann oder alternativ, wie man den Zwischenschritt der Staging-Area überspringen kann. diff --git a/book/02-git-basics/1-git-basics.asc b/book/02-git-basics/1-git-basics.asc deleted file mode 100644 index 77161b5a6..000000000 --- a/book/02-git-basics/1-git-basics.asc +++ /dev/null @@ -1,26 +0,0 @@ -[[_git_basics_chapter]] -== Git Grundlagen - -Wenn Sie nur wenig Zeit haben um Git zu erlernen, dann sollten Sie sich dieses Kapitel zu Gemüte führen. -In diesem Kapitel werden die grundlegenden Git Befehle erklärt, die Sie für den Großteil der täglichen Arbeit mit Git brauchen. -Am Ende des Kapitels sollten Sie in der Lage sein, ein neues Repository anzulegen und zu konfigurieren, Dateien zu versionieren bzw. aus der Versionsverwaltung zu entfernen, Dateien in die Staging-Area hinzuzufügen und schließlich einen Commit durchzuführen. -Außerdem wird gezeigt, wie Sie Git so konfigurieren können, dass es bestimmte Dateien und Dateimuster ignoriert, wie Sie Fehler schnell und einfach rückgängig machen, wie Sie die Historie eines Projekts durchsuchen und Änderungen zwischen Commits nachschlagen, und wie Sie von einem Remote-Repository Daten herunter- bzw. dort hochladen können. - -include::sections/getting-a-repository.asc[] - -include::sections/recording-changes.asc[] - -include::sections/viewing-history.asc[] - -include::sections/undoing.asc[] - -include::sections/remotes.asc[] - -include::sections/tagging.asc[] - -include::sections/aliases.asc[] - -=== Zusammenfassung - -Sie sollten jetzt in der Lage sein, die wichtigsten Git Befehle einsetzen zu können. Folgendes sollte Ihnen jetzt gelingen: Erzeugen oder Klonen eines Repositorys, Änderungen vorzunehmen und zur Staging-Area hinzuzufügen, Commits anzulegen und die Historie aller Commits in einem Repository zu durchsuchen. -Im nächsten Kapitel werden Sie das "Killer"-Feature von Git kennenlernen: das Branch Konzept. diff --git a/book/02-git-basics/images/lifecycle.png b/book/02-git-basics/images/lifecycle.png deleted file mode 100644 index 922b02c09..000000000 Binary files a/book/02-git-basics/images/lifecycle.png and /dev/null differ diff --git a/book/02-git-basics/sections/getting-a-repository.asc b/book/02-git-basics/sections/getting-a-repository.asc index fb5df1e52..e3ea053a5 100644 --- a/book/02-git-basics/sections/getting-a-repository.asc +++ b/book/02-git-basics/sections/getting-a-repository.asc @@ -2,34 +2,34 @@ === Ein Git Repository anlegen Sie haben zwei Möglichkeiten, ein Git Repository auf Ihrem Rechner anzulegen. -Sie können entweder ein existierendes Projekt oder Verzeichnis in ein neues Git Repository importieren. -Oder Sie können ein existierendes Repository von einem Server auf den eigenen Rechner klonen. -==== Ein existierendes Verzeichnis als Git Repository initialisieren +1. Sie können ein lokales Verzeichnis, das sich derzeit nicht unter Versionskontrolle befindet, in ein Git-Repository verwandeln, oder +2. Sie können ein bestehendes Git-Repository von einem anderen Ort aus _klonen_. -<<<<<<< HEAD -Wenn Sie ein bestehendes Projekt in Zukunft versionieren möchten, können Sie dazu in das Hauptverzeichnis des Projekts wechseln und den folgenden Befehl ausführen: -======= -If you're starting to track an existing project in Git, you need to go to the project's directory. If you've never done this, it looks a little different depending on which system you're running: +In beiden Fällen erhalten Sie ein einsatzbereites Git-Repository auf Ihrem lokalen Rechner. -for Linux: +==== Ein Repository in einem bestehenden Verzeichnis einrichten + +Wenn Sie ein Projektverzeichnis haben, das sich derzeit nicht unter Versionskontrolle befindet, und Sie mit der Kontrolle über Git beginnen möchten, müssen Sie zunächst in das Verzeichnis dieses Projekts wechseln. +Wenn Sie dies noch nie getan haben, sieht es je nachdem, welches System Sie verwenden, etwas anders aus: + +für Linux: [source,console] ---- -$ cd /home/user/your_repository +$ cd /home/user/my_project ---- -for Mac: +für macOS: [source,console] ---- -$ cd /Users/user/your_repository +$ cd /Users/user/my_project ---- -for Windows: +für Windows: [source,console] ---- -$ cd /c/user/your_repository +$ cd /c/user/my_project ---- -and type: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +dann folgenden Befehl eingeben: [source,console] ---- @@ -37,9 +37,10 @@ $ git init ---- Der Befehl erzeugt ein Unterverzeichnis `.git`, in dem alle relevanten Git Repository Daten enthalten sind, also ein Git Repository Grundgerüst. -Zu diesem Zeitpunkt werden noch keine Dateien in Git versioniert. (Im Kapitel <<_git_internals>> finden Sie weitere Informationen, welche Dateien im `.git` Verzeichnis enthalten sind und was ihre Aufgabe ist.)(((Git Befehle, init))) +Zu diesem Zeitpunkt werden noch keine Dateien in Git versioniert. +(In Kapitel 10, <>, finden Sie weitere Informationen, welche Dateien im `.git` Verzeichnis enthalten sind und was ihre Aufgabe ist.)(((Git Befehle, init))) -Wenn Sie bereits existierende Dateien versionieren möchten (und es sich nicht nur um ein leeres Verzeichnis handelt), dann sollten Sie den aktuellen Stand in einem initialen Commit einchecken. +Wenn Sie bereits existierende Dateien versionieren möchten (und es sich nicht nur um ein leeres Verzeichnis handelt), dann sollten Sie den aktuellen Stand in einem initialen Commit starten. Mit dem Befehl `git add` legen Sie fest, welche Dateien versioniert werden sollen und mit dem Befehl `git commit` erzeugen Sie einen neuen Commit: [source,console] @@ -49,28 +50,30 @@ $ git add LICENSE $ git commit -m 'initial project version' ---- -Wir werden gleich noch einmal genauer auf diese Befehle eingehen. Im Moment ist nur wichtig, dass Sie verstehen, dass Sie jetzt ein Git Repository erzeugt und einen ersten Commit angelegt haben. +Wir werden gleich noch einmal genauer auf diese Befehle eingehen. +Im Moment ist nur wichtig, dass Sie verstehen, dass Sie jetzt ein Git Repository erzeugt und einen ersten Commit angelegt haben. [[_git_cloning]] ==== Ein existierendes Repository klonen -Wenn Sie eine Kopie eines existierenden Git Repositorys anlegen wollen - z.B. um an einem Projekt mitzuarbeiten - können Sie den Befehl `git clone` verwenden. -Wenn Sie bereits Erfahrung mit einem anderen VCS System, wie Subversion, gesammelt haben, fällt Ihnen bestimmt sofort auf, dass der Befehl `clone` und nicht etwa `checkout` lautet. -Dies ist ein wichtiger Unterschied, den Sie unbedingt verstehen sollten - Anstatt nur eine einfache Arbeitskopie vom Projekt zu erzeugen, lädt Git nahezu alle Daten, die der Server bereithält, auf den lokalen Rechner. -Mit `git clone` wird jede einzelne Version jeder einzelnen Datei, also die gesamte Historie eines Projekts auf den Rechner heruntergeladen. -Wenn ein Repository auf einem Server einmal beschädigt wird (z.B. weil die Festplatte beschädigt wird), kann man tatsächlich jeden beliebigen Klon des Repositorys verwenden, um das Repository auf dem Server wieder in dem Zustand wiederherzustellen, in dem es sich befand, als es geklont wurde (es kann passieren, dass man einige auf dem Server vorhandene Hooks verliert, aber alle versionierten Daten bleiben erhalten. Im Kapitel <<_git_on_the_server>> erfahren Sie dazu nähere Details). +Wenn Sie eine Kopie eines existierenden Git Repositorys anlegen wollen – um beispielsweise an einem Projekt mitzuarbeiten – können Sie den Befehl `git clone` verwenden. +Wenn Sie bereits Erfahrung mit einem anderen VCS System, wie Subversion, gesammelt haben, fällt Ihnen bestimmt sofort auf, dass der Befehl „clone“ und nicht etwa „checkout“ lautet. +Das ist ein wichtiger Unterschied, den Sie unbedingt verstehen sollten – Anstatt nur eine einfache Arbeitskopie vom Projekt zu erzeugen, lädt Git nahezu alle Daten, die der Server bereithält, auf den lokalen Rechner. +Jede Version von jeder Datei der Projekt-Historie wird automatisch heruntergeladen, wenn Sie `git clone` ausführen. +Wenn Ihre Serverfestplatte beschädigt wird, können Sie oft nahezu jeden der Klone auf irgendeinem Client verwenden, um den Server wieder in den Zustand zurückzusetzen, in dem er sich zum Zeitpunkt des Klonens befand (Sie werden vielleicht einige serverseitige Hooks und dergleichen verlieren, aber alle versionierten Daten wären vorhanden - siehe Kapitel 4, <>, für weitere Details). Sie können ein Repository mit dem Befehl `git clone [url]` klonen.(((Git Befehle, clone))) -Um beispielsweise das Repository der linkbaren Git Bibliothek libgit2 zu klonen, führen Sie den folgenden Befehl aus: +Um beispielsweise das Repository der verlinkbaren Git Bibliothek `libgit2` zu klonen, führen Sie den folgenden Befehl aus: [source,console] ---- $ git clone https://github.com/libgit2/libgit2 ---- -Git legt dann ein Verzeichnis ``libgit2'' an, initialisiert in diesem ein `.git` Verzeichnis, lädt alle Daten des Repositorys herunter, und checkt eine Arbeitskopie der aktuellsten Version aus. -Wenn Sie in das neue `libgit2` Verzeichnis wechseln, finden Sie dort die Projektdateien und können gleich mit ihnen loslegen. -Wenn Sie das Repository in ein Verzeichnis mit einem anderen Namen als ``libgit2'' klonen möchten, können Sie das wie folgt durchführen: +Git legt dann ein Verzeichnis `libgit2` an, initialisiert in diesem ein `.git` Verzeichnis, lädt alle Daten des Repositorys herunter, und checkt eine Arbeitskopie der aktuellsten Version aus. +Wenn Sie in das neue `libgit2` Verzeichnis wechseln, finden Sie dort die Projektdateien und können gleich damit arbeiten. + +Wenn Sie das Repository in ein Verzeichnis mit einem anderen Namen als `libgit2` klonen möchten, können Sie das wie folgt durchführen: [source,console] ---- @@ -80,5 +83,5 @@ $ git clone https://github.com/libgit2/libgit2 mylibgit Dieser Befehl tut das gleiche wie der vorhergehende, aber das Zielverzeichnis lautet diesmal `mylibgit`. Git unterstützt eine Reihe unterschiedlicher Übertragungsprotokolle. -Das vorhergehende Beispiel verwendet das `https://` Protokoll, aber Ihnen können auch die Angaben `git://` oder `user@server:path/to/repo.git` begegnen, welche das SSH-Transfer-Protokoll verwenden. -Im Kapitel <<_git_on_the_server>> gehen wir auf die verfügbaren Optionen und deren Vor- und Nachteile ein, die ein Server hat, um Zugriff auf ein Git Repository zu ermöglichen. +Das vorhergehende Beispiel verwendet das `https://` Protokoll, aber Ihnen können auch die Angaben `git://` oder `user@server:path/to/repo.git` begegnen, welches das SSH-Transfer-Protokoll verwendet. +Kapitel 4, <>, stellt alle verfügbaren Optionen vor, die der Server für den Zugriff auf Ihr Git-Repository hat und die Vor- und Nachteile der einzelnen Optionen, die man einrichten kann. diff --git a/book/02-git-basics/sections/recording-changes.asc b/book/02-git-basics/sections/recording-changes.asc index 153a9f80e..a4b2a33df 100644 --- a/book/02-git-basics/sections/recording-changes.asc +++ b/book/02-git-basics/sections/recording-changes.asc @@ -1,24 +1,19 @@ === Änderungen nachverfolgen und im Repository speichern -Sie sollten jetzt ein voll funktionsfähiges Git Repository und eine Arbeitskopie des Projekts auf Ihrer Festplatte haben. -Ab jetzt können Sie Dateien im Projekt bearbeiten und immer dann, wenn das Projekt einen Zustand erreicht hat, den Sie festhalten möchten, können Sie genau diesen Zustand einchecken. +An dieser Stelle sollten Sie ein _originalgetreues_ Git-Repository auf Ihrem lokalen Computer und eine Checkout- oder Arbeitskopie aller seiner Dateien vor sich haben. +Normalerweise werden Sie damit beginnen wollen, Änderungen vorzunehmen und Schnappschüsse dieser Änderungen in Ihr Repository zu übertragen, wenn das Projekt so weit fortgeschritten ist, dass Sie es sichern möchten. -<<<<<<< HEAD -Jede Datei in Ihrem Arbeitsverzeichnis kann sich in einem von zwei Zuständen befinden: Änderungen an der Datei werden verfolgt (engl. tracked) oder eben nicht (engl. untracked). -Alle Dateien, die sich im letzten Schnappschuss (Commit) befanden, werden in der Versionsverwaltung nachverfolgt. Sie können entweder unverändert, modifiziert oder für den nächsten Commit vorgemerkt sein. -Alle anderen Dateien in Ihrem Arbeitsverzeichnis dagegen, sind nicht versioniert: das sind all diejenigen Dateien, die nicht schon im letzten Schnappschuss enthalten waren und die sich nicht in der Staging Area befinden. +Denken Sie daran, dass sich jede Datei in Ihrem Arbeitsverzeichnis in einem von zwei Zuständen befinden kann: _tracked_ oder _untracked_ – Änderungen an der Datei werden verfolgt (engl. _tracked_) oder eben nicht (engl. _untracked_). +Alle Dateien, die sich im letzten Schnappschuss (Commit) befanden, werden in der Versionsverwaltung nachverfolgt. Sie können entweder unverändert, modifiziert oder für den nächsten Commit vorgemerkt (staged) sein. +Kurz gesagt sind getrackte, versionierte Dateien, Daten, die Git kennt. + +Alle anderen Dateien in Ihrem Arbeitsverzeichnis dagegen, sind nicht versioniert: das sind all diejenigen Dateien, die nicht schon im letzten Schnappschuss enthalten waren und die sich nicht in der Staging-Area befinden. Wenn Sie ein Repository zum ersten Mal klonen, sind alle Dateien versioniert und unverändert. Nach dem Klonen wurden sie ja ausgecheckt und bis dahin haben Sie ja auch noch nichts an ihnen verändert. -======= -Remember that each file in your working directory can be in one of two states: tracked or untracked. -Tracked files are files that were in the last snapshot; they can be unmodified, modified, or staged. -Untracked files are everything else – any files in your working directory that were not in your last snapshot and are not in your staging area. -When you first clone a repository, all of your files will be tracked and unmodified because Git just checked them out and you haven't edited anything. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 Sobald Sie anfangen, versionierte Dateien zu bearbeiten, erkennt Git diese als modifiziert, weil sie sich im Vergleich zum letzten Commit verändert haben. -Die geänderten Dateien können Sie dann für den nächsten Commit vormerken und schließlich alle Änderungen, die sich in der Staging-Area befinden, einchecken. Danach geht der Vorgang wieder von vorne los. +Die geänderten Dateien können Sie dann für den nächsten Commit vormerken und schließlich alle Änderungen, die sich in der Staging-Area befinden, einchecken/committen. Danach wiederholt sich der Zyklus. -.Zyklus der Zustände Ihrer Dateien. +.Der Status Ihrer Dateien im Überblick. image::images/lifecycle.png[The lifecycle of the status of your files.] [[_checking_status]] @@ -35,19 +30,13 @@ Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean ---- -<<<<<<< HEAD -Dieser Zustand wird auch als sauberes Arbeitsverzeichnis (engl. clean working directory) bezeichnet. Mit anderen Worten, es gibt keine Dateien, die unter Versionsverwaltung stehen und seit dem letzten Commit geändert wurden – andernfalls würden sie hier aufgelistet werden. +Dieser Zustand wird auch als sauberes Arbeitsverzeichnis (engl. clean working directory) bezeichnet. +Mit anderen Worten, es gibt keine Dateien, die unter Versionsverwaltung stehen und seit dem letzten Commit geändert wurden – andernfalls würden sie hier aufgelistet werden. Außerdem teilt Ihnen der Befehl mit, auf welchem Branch Sie gerade arbeiten und informiert Sie darüber, dass dieser sich im Vergleich zum Branch auf dem Server nicht verändert hat. -In diesem Beispiel ist dies der Branch `master`. Machen Sie sich darüber im Moment keine Gedanken, wir werden im Kapitel <<_git_branching>> auf Branches detailliert eingehen. -======= -This means you have a clean working directory – in other words, none of your tracked files are modified. -Git also doesn't see any untracked files, or they would be listed here. -Finally, the command tells you which branch you're on and informs you that it has not diverged from the same branch on the server. -For now, that branch is always ``master'', which is the default; you won't worry about it here. -<<_git_branching>> will go over branches and references in detail. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 - -Nehmen wir einmal an, Sie fügen eine neue Datei mit dem Namen README zu Ihrem Projekt hinzu. +Momentan ist dieser Zweig immer `master`, was der Vorgabe entspricht; Sie müssen sich jetzt nicht darum kümmern. +Wir werden im Kapitel <> auf Branches detailliert eingehen. + +Nehmen wir einmal an, Sie fügen eine neue Datei mit dem Namen `README` zu Ihrem Projekt hinzu. Wenn die Datei zuvor nicht existiert hat und Sie jetzt `git status` ausführen, zeigt Git die bisher nicht versionierte Datei wie folgt an: [source,console] @@ -64,9 +53,10 @@ Untracked files: nothing added to commit but untracked files present (use "git add" to track) ---- -Alle Dateien, die im Abschnitt ``Untracked files'' aufgelistet werden, sind Dateien, die bisher noch nicht versioniert sind. Dort wird jetzt auch die Datei README angezeigt. +Alle Dateien, die im Abschnitt „Untracked files“ aufgelistet werden, sind Dateien, die bisher noch nicht versioniert sind. Dort wird jetzt auch die Datei `README` angezeigt. Mit anderen Worten, die Datei README wird in diesem Bereich gelistet, weil sie im letzten Schnappschuss nicht enthalten war. Git nimmt eine solche Datei nicht automatisch in die Versionsverwaltung auf, sondern Sie müssen Git dazu ausdrücklich auffordern. -Ansonsten würden generierte Binärdateien oder andere Dateien, die Sie nicht in Ihrem Repository haben möchten, automatisch hinzugefügt werden. Das möchte man in den meisten Fällen vermeiden. Jetzt wollen wir aber Änderungen an der Datei README verfolgen und fügen sie deshalb zur Versionsverwaltung hinzu. +Ansonsten würden generierte Binärdateien oder andere Dateien, die Sie nicht in Ihrem Repository haben möchten, automatisch hinzugefügt werden. Das möchte man in den meisten Fällen vermeiden. +Jetzt wollen wir aber Änderungen an der Datei `README` verfolgen und fügen sie deshalb zur Versionsverwaltung hinzu. [[_tracking_files]] ==== Neue Dateien zur Versionsverwaltung hinzufügen @@ -93,20 +83,15 @@ Changes to be committed: ---- -Dass die Datei für den nächsten Commit vorgemerkt ist, sehen Sie daran, dass sie im Abschnitt ``Changes to be committed'' aufgelistet ist. -Wenn Sie jetzt einen Commit anlegen, wird der Schnappschuss den Zustand der Datei beinhalten, den sie zum Zeitpunkt des Befehls `git add` hatte. -Sie erinnern sich vielleicht daran, wie sie vorhin `git init` und anschließend `git add (files)` ausgeführt haben. Mit diesen Befehlen haben Sie die Dateien in Ihrem Verzeichnis zur Versionsverwaltung hinzugefügt.(((Git Befehle, init)))(((Git Befehle, add))) +Sie können erkennen, dass die Datei für den nächsten Commit vorgemerkt ist, weil sie unter der Rubrik „Changes to be committed“ aufgelistet ist. +Wenn Sie jetzt einen Commit anlegen, wird der Schnappschuss den Zustand der Datei festhalten, den sie zum Zeitpunkt des Befehls `git add` hat. +Sie erinnern sich vielleicht daran, wie Sie vorhin `git init` und anschließend `git add ` ausgeführt haben. Mit diesen Befehlen haben Sie die Dateien in Ihrem Verzeichnis zur Versionsverwaltung hinzugefügt.(((Git Befehle, init)))(((Git Befehle, add))) Der `git add` Befehl akzeptiert einen Pfadnamen einer Datei oder eines Verzeichnisses. Wenn Sie ein Verzeichnis angeben, fügt `git add` alle Dateien in diesem Verzeichnis und allen Unterverzeichnissen rekursiv hinzu. ==== Geänderte Dateien zur Staging-Area hinzufügen -<<<<<<< HEAD Lassen Sie uns jetzt eine bereits versionierte Datei ändern. -Wenn Sie zum Beispiel eine bereits unter Versionsverwaltung stehende Datei mit dem Dateinamen ``CONTRIBUTING.md'' ändern und danach den Befehl `git status` erneut ausführen, erhalten Sie in etwa folgende Ausgabe: -======= -Let's change a file that was already tracked. -If you change a previously tracked file called `CONTRIBUTING.md` and then run your `git status` command again, you get something that looks like this: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Wenn Sie zum Beispiel eine bereits unter Versionsverwaltung stehende Datei mit dem Dateinamen `CONTRIBUTING.md` ändern und danach den Befehl `git status` erneut ausführen, erhalten Sie in etwa folgende Ausgabe: [source,console] ---- @@ -126,19 +111,11 @@ Changes not staged for commit: ---- -<<<<<<< HEAD -Die Datei ``CONTRIBUTING.md'' erscheint im Abschnitt ``Changed but not staged for commit'' – das bedeutet, dass eine versionierte Datei im Arbeitsverzeichnis verändert worden ist, aber noch nicht für den Commit vorgemerkt wurde. -Um sie vorzumerken, führen Sie den Befehl `git add` aus. `git add` wird zu vielen verschiedenen Zwecken eingesetzt. Man verwendet ihn, um neue Dateien zur Versionsverwaltung hinzuzufügen, Dateien für einen Commit vorzumerken und verschiedene andere Dinge – beispielsweise, einen Konflikt aus einem Merge als aufgelöst kennzuzeichnen. -Der Befehl `git add` wird oft missverstanden, viele assoziieren damit, dass damit Dateien zum Projekt hinzufügt werden. Wie Sie aber gerade gelernt haben, wird der Befehl auch noch für viele andere Dinge eingesetzt. Wenn Sie den Befehl `git add` einsetzen, sollten Sie das eher so sehen, dass Sie damit einen bestimmten Inhalt für den nächsten Commit vorbereiten. - -Lassen Sie uns nun die Datei ``CONTRIBUTING.md'' zur Staging-Area hinzufügen und danach das Ergebnis mit `git status` kontrollieren: -======= -The `CONTRIBUTING.md` file appears under a section named ``Changes not staged for commit'' – which means that a file that is tracked has been modified in the working directory but not yet staged. -To stage it, you run the `git add` command. -`git add` is a multipurpose command – you use it to begin tracking new files, to stage files, and to do other things like marking merge-conflicted files as resolved. -It may be helpful to think of it more as ``add this content to the next commit'' rather than ``add this file to the project''.(((git commands, add))) -Let's run `git add` now to stage the `CONTRIBUTING.md` file, and then run `git status` again: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Die Datei `CONTRIBUTING.md` erscheint im Abschnitt „Changed but not staged for commit“ – das bedeutet, dass eine versionierte Datei im Arbeitsverzeichnis verändert worden ist, aber noch nicht für den Commit vorgemerkt wurde. +Um sie vorzumerken, führen Sie den Befehl `git add` aus. +Der Befehl `git add` wird zu vielen verschiedenen Zwecken eingesetzt. Man verwendet ihn, um neue Dateien zur Versionsverwaltung hinzuzufügen, Dateien für einen Commit vorzumerken und verschiedene andere Dinge – beispielsweise, einen Konflikt aus einem Merge als aufgelöst zu kennzeichnen. +Leider wird der Befehl `git add` wird oft missverstanden, viele assoziieren damit, dass damit Dateien zum Projekt hinzufügt werden. Wie Sie aber gerade gelernt haben, wird der Befehl auch noch für viele andere Dinge eingesetzt. Wenn Sie den Befehl `git add` einsetzen, sollten Sie das eher so sehen, dass Sie damit einen bestimmten Inhalt für den nächsten Commit vormerken.(((git commands, add))) +Lassen Sie uns nun mit `git add` die Datei `CONTRIBUTING.md` zur Staging-Area hinzufügen und danach das Ergebnis mit `git status` kontrollieren: [source,console] ---- @@ -154,9 +131,10 @@ Changes to be committed: ---- -Beide Dateien sind nun für den nächsten Commit vorgemerkt. -Nehmen wir an, Sie wollen jetzt aber noch eine weitere Änderung an der Datei `CONTRIBUTING.md` vornehmen, bevor Sie den Commit tatsächlich anlegen. -Sie öffnen die Datei erneut, ändern sie entsprechend ab und eigentlich wären Sie ja jetzt bereit den Commit durchzuführen. Aber Moment, lassen Sie uns vorher noch einmal den Befehl `git status` ausführen: +Beide Dateien sind nun für den nächsten Commit vorgemerkt. +Nehmen wir an, Sie wollen jetzt aber noch eine weitere Änderung an der Datei `CONTRIBUTING.md` vornehmen, bevor Sie den Commit tatsächlich starten. +Sie öffnen die Datei erneut, ändern sie entsprechend ab und eigentlich wären Sie ja jetzt bereit den Commit durchzuführen. +Allerdings lassen Sie uns vorher noch einmal den Befehl `git status` ausführen: [source,console] ---- @@ -178,7 +156,7 @@ Changes not staged for commit: ---- -Huch, was ist das? +Was zum Kuckuck ...? Jetzt wird die Datei `CONTRIBUTING.md` sowohl in der Staging-Area, als auch als geändert aufgelistet. Wie ist das möglich? Die Erklärung dafür ist, dass Git eine Datei in exakt dem Zustand für den Commit vormerkt, in dem sie sich befindet, wenn Sie den Befehl `git add` ausführen. @@ -198,11 +176,11 @@ Changes to be committed: modified: CONTRIBUTING.md ---- -==== Short Status +==== Kompakter Status -While the `git status` output is pretty comprehensive, it's also quite wordy. -Git also has a short status flag so you can see your changes in a more compact way. -If you run `git status -s` or `git status --short` you get a far more simplified output from the command: +Die Ausgabe von `git status` ist sehr umfassend und auch ziemlich wortreich. +Git hat auch ein Kurzformat, mit dem Sie Ihre Änderungen kompakter sehen können. +Wenn Sie `git status -s` oder `git status -short` ausführen, erhalten Sie eine kürzere Darstellung des Befehls: [source,console] ---- @@ -214,18 +192,18 @@ M lib/simplegit.rb ?? LICENSE.txt ---- -New files that aren't tracked have a `??` next to them, new files that have been added to the staging area have an `A`, modified files have an `M` and so on. -There are two columns to the output - the left-hand column indicates the status of the staging area and the right-hand column indicates the status of the working tree. -So for example in that output, the `README` file is modified in the working directory but not yet staged, while the `lib/simplegit.rb` file is modified and staged. -The `Rakefile` was modified, staged and then modified again, so there are changes to it that are both staged and unstaged. +Neue Dateien, die nicht versioniert werden, haben `??` neben sich, neue Dateien, die dem Staging-Area hinzugefügt wurden, haben ein `A`, geänderte Dateien haben ein `M` usw. +Es gibt zwei Spalten für die Ausgabe – die linke Spalte zeigt den Status der Staging-Area und die rechte Spalte den Status des Verzeichnisbaums. +So ist beispielsweise in der Bildschirmausgabe oben, die Datei `README` im Arbeitsverzeichnis geändert, aber noch nicht staged, während die Datei `lib/simplegit.rb` geändert und staged ist. +Das `Rakefile` wurde modifiziert, staged und dann wieder modifiziert, so dass es Änderungen an ihm gibt, die sowohl staged als auch unstaged sind. [[_ignoring]] -==== Ignoring Files +==== Ignorieren von Dateien -Often, you'll have a class of files that you don't want Git to automatically add or even show you as being untracked. -These are generally automatically generated files such as log files or files produced by your build system. -In such cases, you can create a file listing patterns to match them named `.gitignore`.(((ignoring files))) -Here is an example `.gitignore` file: +Häufig gibt es eine Reihe von Dateien, die Git nicht automatisch hinzufügen oder schon gar nicht als „nicht versioniert“ (eng. untracked) anzeigen soll. +Dazu gehören in der Regel automatisch generierte Dateien, wie Log-Dateien oder Dateien, die von Ihrem Build-System erzeugt werden. +In solchen Fällen können Sie die Datei `.gitignore` erstellen, die eine Liste mit Vergleichsmustern enthält.(((ignoring files))) +Hier ist eine `.gitignore` Beispieldatei: [source,console] ---- @@ -234,28 +212,28 @@ $ cat .gitignore *~ ---- -The first line tells Git to ignore any files ending in ``.o'' or ``.a'' – object and archive files that may be the product of building your code. -The second line tells Git to ignore all files whose names end with a tilde (`~`), which is used by many text editors such as Emacs to mark temporary files. -You may also include a log, tmp, or pid directory; automatically generated documentation; and so on. -Setting up a `.gitignore` file before you get going is generally a good idea so you don't accidentally commit files that you really don't want in your Git repository. +Die erste Zeile weist Git an, alle Dateien zu ignorieren, die auf „.o“ oder „.a“ enden – Objekt- und Archivdateien, die das Ergebnis der Codegenerierung sein könnten. +Die zweite Zeile weist Git an, alle Dateien zu ignorieren, deren Name mit einer Tilde (`~`) enden, was von vielen Texteditoren wie Emacs zum Markieren temporärer Dateien verwendet wird. +Sie können auch ein Verzeichnis log, tmp oder pid hinzufügen, eine automatisch generierte Dokumentation usw. +Es ist im Allgemeinen eine gute Idee, die `.gitignore` Datei für Ihr neues Repository einzurichten, noch bevor Sie loslegen. So können Sie nicht versehentlich Dateien committen, die Sie wirklich nicht in Ihrem Git-Repository haben möchten. -The rules for the patterns you can put in the `.gitignore` file are as follows: +Die Richtlinien für Vergleichsmuster, die Sie in der Datei `.gitignore` eingeben können, lauten wie folgt: -* Blank lines or lines starting with `#` are ignored. -* Standard glob patterns work. -* You can start patterns with a forward slash (`/`) to avoid recursivity. -* You can end patterns with a forward slash (`/`) to specify a directory. -* You can negate a pattern by starting it with an exclamation point (`!`). +* Leerzeilen oder Zeilen, die mit `#` beginnen, werden ignoriert. +* Standard Platzhalter-Zeichen funktionieren und werden rekursiv im gesamten Verzeichnisbaum angewendet. +* Sie können Vergleichsmuster mit einem Schrägstrich (`/`) **beginnen**, um die Rekursivität zu verhindern. +* Sie können Vergleichsmuster mit einem Schrägstrich (`/`) **beenden**, um ein Verzeichnis anzugeben. +* Sie können ein Vergleichsmuster verbieten, indem Sie es mit einem Ausrufezeichen (`!`) beginnen. -Glob patterns are like simplified regular expressions that shells use. -An asterisk (`*`) matches zero or more characters; `[abc]` matches any character inside the brackets (in this case a, b, or c); a question mark (`?`) matches a single character; and brackets enclosing characters separated by a hyphen (`[0-9]`) matches any character between them (in this case 0 through 9). -You can also use two asterisks to match nested directories; `a/**/z` would match `a/z`, `a/b/z`, `a/b/c/z`, and so on. +Platzhalter-Zeichen sind wie einfache, reguläre Ausdrücke, die von der Shell genutzt werden. +Ein Sternchen (`*`) entspricht null oder mehr Zeichen; `[abc]` entspricht jedem Zeichen innerhalb der eckigen Klammern (in diesem Fall a, b oder c); ein Fragezeichen (`?`) entspricht einem einzelnen Zeichen und eckige Klammern, die durch einen Bindestrich (`[0-9]`) getrennte Zeichen einschließen, passen zu jedem Zeichen dazwischen (in diesem Fall von 0 bis 9). +Sie können auch zwei Sterne verwenden, um verschachtelte Verzeichnisse abzugleichen; `a/**/z` würde zu `a/z`, `a/b/z`, `a/b/c/z`, `a/b/c/z`, usw. passen. -Here is another example .gitignore file: +Hier ist eine weitere `.gitignore` Beispieldatei: [source] ---- -# no .a files +# ignore all .a files *.a # but do track lib.a, even though you're ignoring .a files above @@ -264,31 +242,41 @@ Here is another example .gitignore file: # only ignore the TODO file in the current directory, not subdir/TODO /TODO -# ignore all files in the build/ directory +# ignore all files in any directory named build build/ # ignore doc/notes.txt, but not doc/server/arch.txt doc/*.txt -# ignore all .pdf files in the doc/ directory +# ignore all .pdf files in the doc/ directory and any of its subdirectories doc/**/*.pdf ---- [TIP] ==== -GitHub maintains a fairly comprehensive list of good `.gitignore` file examples for dozens of projects and languages at https://github.com/github/gitignore[] if you want a starting point for your project. +GitHub unterhält eine ziemlich umfassende Liste guter `.gitignore` Beispiel-Dateien für Dutzende von Projekten und Sprachen auf https://github.com/github/gitignore[], falls Sie einen Ansatzpunkt für Ihr Projekt suchen. +==== + +[NOTE] +==== +Im einfachsten Fall kann ein Repository eine einzelne `.gitignore` Datei in seinem Root-Verzeichnis haben, die rekursiv für das gesamte Repository gilt. +Es ist aber auch möglich, weitere `.gitignore` Dateien in Unterverzeichnissen anzulegen. +Die Regeln dieser verschachtelten `.gitignore` Dateien gelten nur für die in dem Verzeichnis (und unterhalb) liegenden Dateien. +(Das Linux-Kernel-Source-Repository hat beispielsweise 206 `.gitignore` Dateien.) + +Es würde den Rahmen dieses Buches sprengen detaillierter auf den Einsatz mehrerer `.gitignore` Dateien einzugehen; siehe die Manpage `man gitignore` für weitere Innformationen. ==== [[_git_diff_staged]] -==== Viewing Your Staged and Unstaged Changes +==== Überprüfen der Staged und Unstaged Änderungen -If the `git status` command is too vague for you – you want to know exactly what you changed, not just which files were changed – you can use the `git diff` command.(((git commands, diff))) -We'll cover `git diff` in more detail later, but you'll probably use it most often to answer these two questions: What have you changed but not yet staged? -And what have you staged that you are about to commit? -Although `git status` answers those questions very generally by listing the file names, `git diff` shows you the exact lines added and removed – the patch, as it were. +Wenn der Befehl `git status` für Sie zu vage ist – Sie wollen genau wissen, was Sie geändert haben, nicht nur welche Dateien geändert wurden – können Sie den Befehl `git diff` verwenden.(((git commands, diff))) +Wir werden `git diff` später ausführlicher behandeln, aber Sie werden es wahrscheinlich am häufigsten verwenden, um diese beiden Fragen zu beantworten: Was hat sich geändert, ist aber noch nicht zum Commit vorgemerkt (engl. staged)? +Und was haben Sie zum Commit vorgemerkt und können es demnächst committen? +Der Befehl `git status` beantwortet diese Fragen ganz allgemein, indem er die Dateinamen auflistet, `git diff` zeigt Ihnen aber genau die hinzugefügten und entfernten Zeilen – sozusagen den Patch. -Let's say you edit and stage the `README` file again and then edit the `CONTRIBUTING.md` file without staging it. -If you run your `git status` command, you once again see something like this: +Nehmen wir an, Sie bearbeiten und merken die Datei `README` zum Commit vor (eng. stage) und bearbeiten dann die Datei `CONTRIBUTING.md`, ohne sie zu „stagen“. +Wenn Sie den Befehl `git status` ausführen, sehen Sie erneut so etwas wie das hier: [source,console] ---- @@ -307,7 +295,7 @@ Changes not staged for commit: modified: CONTRIBUTING.md ---- -To see what you've changed but not yet staged, type `git diff` with no other arguments: +Um die Änderungen zu sehen, die Sie noch nicht zum Commit vorgemerkt haben, geben Sie den Befehl `git diff`, ohne weitere Argumente, ein: [source,console] ---- @@ -328,11 +316,11 @@ index 8ebb991..643e24f 100644 that highlights your work in progress (and note in the PR title that it's ---- -That command compares what is in your working directory with what is in your staging area. -The result tells you the changes you've made that you haven't yet staged. +Dieses Kommando vergleicht, was sich in Ihrem Arbeitsverzeichnis befindet, mit dem, was sich in Ihrer Staging-Area befindet. +Die Bildschirmanzeige gibt Ihnen an, welche Änderungen Sie vorgenommen haben, die noch nicht „gestaged“ sind. -If you want to see what you've staged that will go into your next commit, you can use `git diff --staged`. -This command compares your staged changes to your last commit: +Wenn Sie wissen wollen, was Sie zum Commit vorgemerkt haben, das in Ihren nächsten Commit einfließt, können Sie `git diff --staged` verwenden. +Dieser Befehl vergleicht Ihre zum Commit vorgemerkten Änderungen mit Ihrem letzten Commit: [source,console] ---- @@ -346,11 +334,11 @@ index 0000000..03902a1 +My Project ---- -It's important to note that `git diff` by itself doesn't show all changes made since your last commit – only changes that are still unstaged. -This can be confusing, because if you've staged all of your changes, `git diff` will give you no output. +Es ist wichtig zu wissen, dass `git diff` von sich aus nicht alle Änderungen seit Ihrem letzten Commit anzeigt – nur die Änderungen, die noch „unstaged“ sind. +Wenn Sie alle Ihre Änderungen bereits „gestaged“ haben, wird `git diff` Ihnen keine Antwort geben. -For another example, if you stage the `CONTRIBUTING.md` file and then edit it, you can use `git diff` to see the changes in the file that are staged and the changes that are unstaged. -If our environment looks like this: +Ein weiteres Beispiel: wenn Sie die Datei `CONTRIBUTING.md` zum Commit vormerken und dann wieder bearbeiten, können Sie mit `git diff` die Änderungen in der „staged“ Datei und die „unstaged“ Änderungen sehen. +Wenn Sie folgendes gemacht haben: [source,console] ---- @@ -371,7 +359,7 @@ Changes not staged for commit: modified: CONTRIBUTING.md ---- -Now you can use `git diff` to see what is still unstaged: +Jetzt können Sie mit `git diff` sehen, was noch nicht zum Commit vorgemerkt ist: [source,console] ---- @@ -387,7 +375,7 @@ index 643e24f..87f08c8 100644 +# test line ---- -and `git diff --cached` to see what you've staged so far (`--staged` and `--cached` are synonyms): +und `git diff --cached` zeigt Ihnen, was Sie bisher zum Commit vorgemerkt haben (`--staged` und `--cached` sind Synonyme, sie bewirken das Gleiche): [source,console] ---- @@ -409,32 +397,32 @@ index 8ebb991..643e24f 100644 ---- [NOTE] -.Git Diff in an External Tool +.Git Diff mit einem externen Tool ==== -We will continue to use the `git diff` command in various ways throughout the rest of the book. -There is another way to look at these diffs if you prefer a graphical or external diff viewing program instead. -If you run `git difftool` instead of `git diff`, you can view any of these diffs in software like emerge, vimdiff and many more (including commercial products). -Run `git difftool --tool-help` to see what is available on your system. +Wir werden den Befehl `git diff` im weiteren Verlauf des Buches auf vielfältige Weise verwenden. +Es gibt eine weitere Methode, diese Diffs zu betrachten, wenn Sie lieber ein graphisches oder externes Diff-Viewing-Programm bevorzugen. +Wenn Sie `git difftool` anstelle von `git diff` verwenden, können Sie alle diese Unterschiede in einer Software wie emerge, vimdiff und viele andere (einschließlich kommerzieller Produkte) anzeigen lassen. +Führen Sie den Befehl `git difftool --tool-help` aus, um zu sehen, was auf Ihrem System verfügbar ist. ==== [[_committing_changes]] -==== Committing Your Changes +==== Die Änderungen committen -Now that your staging area is set up the way you want it, you can commit your changes. -Remember that anything that is still unstaged – any files you have created or modified that you haven't run `git add` on since you edited them – won't go into this commit. -They will stay as modified files on your disk. -In this case, let's say that the last time you ran `git status`, you saw that everything was staged, so you're ready to commit your changes.(((git commands, status))) -The simplest way to commit is to type `git commit`:(((git commands, commit))) +Nachdem Ihre Staging-Area nun so eingerichtet ist, wie Sie es wünschen, können Sie Ihre Änderungen committen. +Denken Sie daran, dass alles, was noch nicht zum Commit vorgemerkt ist – alle Dateien, die Sie erstellt oder geändert haben und für die Sie seit Ihrer Bearbeitung nicht mehr `git add` ausgeführt haben – nicht in diesen Commit einfließen werden. +Sie bleiben aber als geänderte Dateien auf Ihrer Festplatte erhalten. +In diesem Beispiel nehmen wir an, dass Sie beim letzten Mal, als Sie `git status` ausgeführt haben, gesehen haben, dass alles zum Commit vorgemerkt wurde und bereit sind, Ihre Änderungen zu committen.(((git commands, status))) +Am einfachsten ist es, wenn Sie `git commit` eingeben:(((git commands, commit))) [source,console] ---- $ git commit ---- -Doing so launches your editor of choice. -(This is set by your shell's `$EDITOR` environment variable – usually vim or emacs, although you can configure it with whatever you want using the `git config --global core.editor` command as you saw in <<_getting_started>>).(((editor, changing default)))(((git commands, config))) +Dadurch wird der Editor Ihrer Wahl gestartet. +(Das wird durch die Umgebungsvariable `EDITOR` Ihrer Shell festgelegt – normalerweise vim oder emacs, wie Sie es mit dem Befehl `git config --global core.editor` beliebig konfigurieren können und wie Sie es in Kapitel 1, <>, gesehen haben).(((editor, changing default)))(((git commands, config))) -The editor displays the following text (this example is a Vim screen): +Der Editor zeigt den folgenden Text an (dieses Beispiel ist eine Vim-Ansicht): [source] ---- @@ -454,13 +442,13 @@ The editor displays the following text (this example is a Vim screen): ".git/COMMIT_EDITMSG" 9L, 283C ---- -You can see that the default commit message contains the latest output of the `git status` command commented out and one empty line on top. -You can remove these comments and type your commit message, or you can leave them there to help you remember what you're committing. -(For an even more explicit reminder of what you've modified, you can pass the `-v` option to `git commit`. -Doing so also puts the diff of your change in the editor so you can see exactly what changes you're committing.) -When you exit the editor, Git creates your commit with that commit message (with the comments and diff stripped out). +Sie können erkennen, dass die Standard-Commit-Meldung die neueste Ausgabe des auskommentierten Befehls `git status` und eine leere Zeile darüber enthält. +Sie können diese Kommentare entfernen und Ihre Commit-Nachricht eingeben oder Sie können sie dort stehen lassen, damit Sie sich merken können, was Sie committen. +(Für eine noch bessere Gedächtnisstütze über das, was Sie geändert haben, können Sie die Option `-v` an `git commit` übergeben. +Dadurch wird auch die Differenz Ihrer Änderung in den Editor geschrieben, so dass Sie genau sehen können, welche Änderungen Sie committen.) +Wenn Sie den Editor verlassen, erstellt Git Ihren Commit mit dieser Commit-Nachricht (mit den Kommentaren und ausgeblendetem diff). -Alternatively, you can type your commit message inline with the `commit` command by specifying it after a `-m` flag, like this: +Alternativ können Sie Ihre Commit-Nachricht auch inline mit dem Befehl `commit -m` eingeben. Das `-m` Flag ermöglicht die direkte Eingabe eines Kommentar-Textes: [source,console] ---- @@ -470,19 +458,19 @@ $ git commit -m "Story 182: Fix benchmarks for speed" create mode 100644 README ---- -Now you've created your first commit! -You can see that the commit has given you some output about itself: which branch you committed to (`master`), what SHA-1 checksum the commit has (`463dc4f`), how many files were changed, and statistics about lines added and removed in the commit. +Jetzt haben Sie Ihren ersten Commit erstellt! +Sie können sehen, dass der Commit eine Nachricht über sich selbst ausgegeben hat: in welchen Branch Sie committed haben (`master`), welche SHA-1-Prüfsumme der Commit hat (`463dc4f`), wie viele Dateien geändert wurden, und Statistiken über hinzugefügte und entfernte Zeilen im Commit. -Remember that the commit records the snapshot you set up in your staging area. -Anything you didn't stage is still sitting there modified; you can do another commit to add it to your history. -Every time you perform a commit, you're recording a snapshot of your project that you can revert to or compare to later. +Denken Sie daran, dass der Commit den Snapshot aufzeichnet, den Sie in Ihrer Staging-Area eingerichtet haben. +Alles, was von Ihnen nicht zum Commit vorgemerkt wurde, liegt immer noch als modifiziert da. Sie können einen weiteren Commit durchführen, um es zu Ihrer Historie hinzuzufügen. +Jedes Mal, wenn Sie einen Commit ausführen, zeichnen Sie einen Schnappschuss Ihres Projekts auf, auf den Sie zurückgreifen oder mit einem späteren Zeitpunkt vergleichen können. -==== Skipping the Staging Area +==== Die Staging Area überspringen (((staging area, skipping))) -Although it can be amazingly useful for crafting commits exactly how you want them, the staging area is sometimes a bit more complex than you need in your workflow. -If you want to skip the staging area, Git provides a simple shortcut. -Adding the `-a` option to the `git commit` command makes Git automatically stage every file that is already tracked before doing the commit, letting you skip the `git add` part: +Obwohl es außerordentlich nützlich sein kann, Commits so zu erstellen, wie Sie es wünschen, ist die Staging-Area manchmal etwas komplexer, als Sie es für Ihren Workflow benötigen. +Wenn Sie die Staging-Area überspringen möchten, bietet Git eine einfache Kurzform. +Durch das Hinzufügen der Option `-a` zum Befehl `git commit` wird jede Datei, die bereits vor dem Commit versioniert war, automatisch von Git zum Commit vorgemerkt (engl. staged), so dass Sie den Teil `git add` überspringen können: [source,console] ---- @@ -501,18 +489,18 @@ $ git commit -a -m 'added new benchmarks' 1 file changed, 5 insertions(+), 0 deletions(-) ---- -Notice how you don't have to run `git add` on the `CONTRIBUTING.md` file in this case before you commit. -That's because the `-a` flag includes all changed files. -This is convenient, but be careful; sometimes this flag will cause you to include unwanted changes. +Beachten Sie, dass Sie in diesem Fall `git add` nicht auf der Datei `CONTRIBUTING.md` ausführen müssen, bevor Sie committen. +Das liegt daran, dass das `-a` Flag alle geänderten Dateien einschließt. +Das ist bequem, aber seien Sie vorsichtig. Manchmal führt dieses Flag dazu, dass Sie ungewollte Änderungen vornehmen. [[_removing_files]] -==== Removing Files +==== Dateien löschen (((files, removing))) -To remove a file from Git, you have to remove it from your tracked files (more accurately, remove it from your staging area) and then commit. -The `git rm` command does that, and also removes the file from your working directory so you don't see it as an untracked file the next time around. +Um eine Datei aus Git zu entfernen, müssen Sie sie aus der Versionsverwaltung entfernen (genauer gesagt, aus Ihrem Staging-Bereich löschen) und dann committen. +Der Befehl `git rm` erledigt das und entfernt die Datei auch aus Ihrem Arbeitsverzeichnis, so dass Sie sie beim nächsten Mal nicht mehr als „untracked“ Datei sehen. -If you simply remove the file from your working directory, it shows up under the ``Changed but not updated'' (that is, _unstaged_) area of your `git status` output: +Wenn Sie die Datei einfach aus Ihrem Arbeitsverzeichnis entfernen, erscheint sie unter dem "Changes not staged for commit"-Bereich (das ist die _unstaged_-Area) Ihrer `git status`-Ausgabe: [source,console] ---- @@ -529,7 +517,7 @@ Changes not staged for commit: no changes added to commit (use "git add" and/or "git commit -a") ---- -Then, if you run `git rm`, it stages the file's removal: +Wenn Sie dann `git rm` ausführen, wird die Entfernung der Datei zum Commit vorgemerkt: [source,console] ---- @@ -544,58 +532,58 @@ Changes to be committed: deleted: PROJECTS.md ---- -The next time you commit, the file will be gone and no longer tracked. -If you modified the file and added it to the index already, you must force the removal with the `-f` option. -This is a safety feature to prevent accidental removal of data that hasn't yet been recorded in a snapshot and that can't be recovered from Git. +Wenn Sie das nächste Mal einen Commit ausführen, ist die Datei weg und ist nicht mehr versioniert (engl. tracked). +Wenn Sie die Datei geändert oder bereits zur Staging-Area hinzugefügt haben, müssen Sie das Entfernen mit der Option `-f` erzwingen. +Hierbei handelt es sich um eine Sicherheitsfunktion, die ein versehentliches Entfernen von Dateien verhindert, die noch nicht in einem Snapshot aufgezeichnet wurden und die nicht von Git wiederhergestellt werden können. -Another useful thing you may want to do is to keep the file in your working tree but remove it from your staging area. -In other words, you may want to keep the file on your hard drive but not have Git track it anymore. -This is particularly useful if you forgot to add something to your `.gitignore` file and accidentally staged it, like a large log file or a bunch of `.a` compiled files. -To do this, use the `--cached` option: +Eine weitere nützliche Sache, die Sie möglicherweise nutzen möchten, ist, die Datei in Ihrem Verzeichnisbaum zu behalten, sie aber aus Ihrer Staging-Area zu entfernen. +Mit anderen Worten, Sie können die Datei auf Ihrer Festplatte behalten, aber nicht mehr von Git protokollieren/versionieren lassen. +Das ist besonders dann nützlich, wenn Sie vergessen haben, etwas zu Ihrer `.gitignore` Datei hinzuzufügen und diese versehentlich „gestaged“ haben, wie eine große Logdatei oder eine Reihe von `.a` kompilierten Dateien. +Das erreichen Sie mit der Option `--cacheed`: [source,console] ---- $ git rm --cached README ---- -You can pass files, directories, and file-glob patterns to the `git rm` command. -That means you can do things such as: +Sie können Dateien, Verzeichnisse und Platzhalter-Zeichen an den Befehl `git rm` übergeben. +Das bedeutet, dass Sie folgende Möglichkeit haben: [source,console] ---- $ git rm log/\*.log ---- -Note the backslash (`\`) in front of the `*`. -This is necessary because Git does its own filename expansion in addition to your shell's filename expansion. -This command removes all files that have the `.log` extension in the `log/` directory. -Or, you can do something like this: +Beachten Sie den Backslash (`\`) vor dem `*`. +Der ist notwendig, weil Git zusätzlich zur Dateinamen-Erweiterung Ihrer Shell eine eigene Dateinamen-Erweiterung vornimmt. +Mit dem Befehl oben werden alle Dateien entfernt, die die Erweiterung `.log` im Verzeichnis `log/` haben. +oder, Sie können etwas Ähnliches ausführen: [source,console] ---- $ git rm \*~ ---- -This command removes all files whose names end with a `~`. +Das Kommando entfernt alle Dateien, deren Name mit einer `~` endet. [[_git_mv]] -==== Moving Files +==== Dateien verschieben (((files, moving))) -Unlike many other VCS systems, Git doesn't explicitly track file movement. -If you rename a file in Git, no metadata is stored in Git that tells it you renamed the file. -However, Git is pretty smart about figuring that out after the fact – we'll deal with detecting file movement a bit later. +Im Gegensatz zu vielen anderen VCS-Systemen verfolgt (engl. track) Git das Verschieben von Dateien nicht ausdrücklich. +Wenn Sie eine Datei in Git umbenennen, werden keine Metadaten in Git gespeichert, die dem System mitteilen, dass Sie die Datei umbenannt haben. +Allerdings ist Git ziemlich clever, das im Nachhinein herauszufinden – wir werden uns etwas später mit der Erkennung von Datei-Verschiebungen befassen. -Thus it's a bit confusing that Git has a `mv` command. -If you want to rename a file in Git, you can run something like: +Daher ist es etwas verwirrend, dass Git einen Befehl `mv` vorweisen kann. +Wenn Sie eine Datei in Git umbenennen möchten, dann können Sie beispielsweise Folgendes ausführen: [source,console] ---- $ git mv file_from file_to ---- -and it works fine. -In fact, if you run something like this and look at the status, you'll see that Git considers it a renamed file: +Das funktioniert gut. +Tatsache ist, wenn Sie so einen Befehl ausführen und sich den Status ansehen, werden Sie sehen, dass Git es für eine umbenannte Datei hält: [source,console] ---- @@ -609,7 +597,7 @@ Changes to be committed: renamed: README.md -> README ---- -However, this is equivalent to running something like this: +Unabhängig davon, ist dieser Befehl zu dem Folgenden gleichwertig: [source,console] ---- @@ -618,6 +606,6 @@ $ git rm README.md $ git add README ---- -Git figures out that it's a rename implicitly, so it doesn't matter if you rename a file that way or with the `mv` command. -The only real difference is that `git mv` is one command instead of three – it's a convenience function. -More importantly, you can use any tool you like to rename a file, and address the add/rm later, before you commit. +Git erkennt, dass es sich um eine umbenannte Datei handelt, so dass es egal ist, ob Sie eine Datei auf diese Weise oder mit dem Befehl `mv` umbenennen. +Der alleinige, reale Unterschied ist, dass `git mv` ein einziger Befehl ist statt deren drei - es ist eine Komfortfunktion. +Wichtiger ist, dass Sie jedes beliebige Tool verwenden können, um eine Datei umzubenennen und das add/rm später aufrufen können, bevor Sie committen. diff --git a/book/02-git-basics/sections/remotes.asc b/book/02-git-basics/sections/remotes.asc index fed485234..a150fbf6b 100644 --- a/book/02-git-basics/sections/remotes.asc +++ b/book/02-git-basics/sections/remotes.asc @@ -8,11 +8,19 @@ Collaborating with others involves managing these remote repositories and pushin Managing remote repositories includes knowing how to add remote repositories, remove remotes that are no longer valid, manage various remote branches and define them as being tracked or not, and more. In this section, we'll cover some of these remote-management skills. +[NOTE] +.Remote repositories can be on your local machine. +==== +It is entirely possible that you can be working with a ``remote'' repository that is, in fact, on the same host you are. +The word ``remote'' does not necessarily imply that the repository is somewhere else on the network or Internet, only that it is elsewhere. +Working with such a remote repository would still involve all the standard pushing, pulling and fetching operations as with any other remote. +==== + ==== Showing Your Remotes To see which remote servers you have configured, you can run the `git remote` command.(((git commands, remote))) It lists the shortnames of each remote handle you've specified. -If you've cloned your repository, you should at least see origin – that is the default name Git gives to the server you cloned from: +If you've cloned your repository, you should at least see `origin` -- that is the default name Git gives to the server you cloned from: [source,console] ---- @@ -59,11 +67,11 @@ origin git@github.com:mojombo/grit.git (push) This means we can pull contributions from any of these users pretty easily. We may additionally have permission to push to one or more of these, though we can't tell that here. -Notice that these remotes use a variety of protocols; we'll cover more about this in <<_git_on_the_server>>. +Notice that these remotes use a variety of protocols; we'll cover more about this in <>. ==== Adding Remote Repositories -We've mentioned and given some demonstrations of how the 'clone' command implicitly adds the `origin` remote for you. +We've mentioned and given some demonstrations of how the `git clone` command implicitly adds the `origin` remote for you. Here's how to add a new remote explicitly.(((git commands, remote))) To add a new remote Git repository as a shortname you can reference easily, run `git remote add `: @@ -94,8 +102,8 @@ From https://github.com/paulboone/ticgit * [new branch] ticgit -> pb/ticgit ---- -Paul's master branch is now accessible locally as `pb/master` – you can merge it into one of your branches, or you can check out a local branch at that point if you want to inspect it. -(We'll go over what branches are and how to use them in much more detail in <<_git_branching>>.) +Paul's master branch is now accessible locally as `pb/master` -- you can merge it into one of your branches, or you can check out a local branch at that point if you want to inspect it. +(We'll go over what branches are and how to use them in much more detail in <>.) [[_fetching_and_pulling]] ==== Fetching and Pulling from Your Remotes @@ -104,7 +112,7 @@ As you just saw, to get data from your remote projects, you can run:(((git comma [source,console] ---- -$ git fetch [remote-name] +$ git fetch ---- The command goes out to that remote project and pulls down all the data from that remote project that you don't have yet. @@ -112,10 +120,10 @@ After you do this, you should have references to all the branches from that remo If you clone a repository, the command automatically adds that remote repository under the name ``origin''. So, `git fetch origin` fetches any new work that has been pushed to that server since you cloned (or last fetched from) it. -It's important to note that the `git fetch` command only downloads the data to your local repository – it doesn't automatically merge it with any of your work or modify what you're currently working on. +It's important to note that the `git fetch` command only downloads the data to your local repository -- it doesn't automatically merge it with any of your work or modify what you're currently working on. You have to merge it manually into your work when you're ready. -If your current branch is set up to track a remote branch (see the next section and <<_git_branching>> for more information), you can use the `git pull` command to automatically fetch and then merge that remote branch into your current branch.(((git commands, pull))) +If your current branch is set up to track a remote branch (see the next section and <> for more information), you can use the `git pull` command to automatically fetch and then merge that remote branch into your current branch.(((git commands, pull))) This may be an easier or more comfortable workflow for you; and by default, the `git clone` command automatically sets up your local master branch to track the remote master branch (or whatever the default branch is called) on the server you cloned from. Running `git pull` generally fetches data from the server you originally cloned from and automatically tries to merge it into the code you're currently working on. @@ -123,7 +131,7 @@ Running `git pull` generally fetches data from the server you originally cloned ==== Pushing to Your Remotes When you have your project at a point that you want to share, you have to push it upstream. -The command for this is simple: `git push [remote-name] [branch-name]`.(((git commands, push))) +The command for this is simple: `git push `.(((git commands, push))) If you want to push your master branch to your `origin` server (again, cloning generally sets up both of those names for you automatically), then you can run this to push any commits you've done back up to the server: [source,console] @@ -134,12 +142,12 @@ $ git push origin master This command works only if you cloned from a server to which you have write access and if nobody has pushed in the meantime. If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You'll have to fetch their work first and incorporate it into yours before you'll be allowed to push. -See <<_git_branching>> for more detailed information on how to push to remote servers. +See <> for more detailed information on how to push to remote servers. [[_inspecting_remote]] ==== Inspecting a Remote -If you want to see more information about a particular remote, you can use the `git remote show [remote-name]` command.(((git commands, remote))) +If you want to see more information about a particular remote, you can use the `git remote show ` command.(((git commands, remote))) If you run this command with a particular shortname, such as `origin`, you get something like this: [source,console] @@ -192,7 +200,7 @@ $ git remote show origin This command shows which branch is automatically pushed to when you run `git push` while on certain branches. It also shows you which remote branches on the server you don't yet have, which remote branches you have that have been removed from the server, and multiple local branches that are able to merge automatically with their remote-tracking branch when you run `git pull`. -==== Removing and Renaming Remotes +==== Renaming and Removing Remotes You can run `git remote rename` to change a remote's shortname.(((git commands, remote))) For instance, if you want to rename `pb` to `paul`, you can do so with `git remote rename`: @@ -208,7 +216,7 @@ paul It's worth mentioning that this changes all your remote-tracking branch names, too. What used to be referenced at `pb/master` is now at `paul/master`. -If you want to remove a remote for some reason – you've moved the server or are no longer using a particular mirror, or perhaps a contributor isn't contributing anymore – you can either use `git remote remove` or `git remote rm`: +If you want to remove a remote for some reason -- you've moved the server or are no longer using a particular mirror, or perhaps a contributor isn't contributing anymore -- you can either use `git remote remove` or `git remote rm`: [source,console] ---- @@ -216,3 +224,5 @@ $ git remote remove paul $ git remote origin ---- + +Once you delete the reference to a remote this way, all remote-tracking branches and configuration settings associated with that remote are also deleted. diff --git a/book/02-git-basics/sections/tagging.asc b/book/02-git-basics/sections/tagging.asc index abf23158c..0ae6ae7ac 100644 --- a/book/02-git-basics/sections/tagging.asc +++ b/book/02-git-basics/sections/tagging.asc @@ -2,27 +2,27 @@ === Tagging (((tags))) -Like most VCSs, Git has the ability to tag specific points in history as being important. -Typically people use this functionality to mark release points (v1.0, and so on). -In this section, you'll learn how to list the available tags, how to create new tags, and what the different types of tags are. +Like most VCSs, Git has the ability to tag specific points in a repository's history as being important. +Typically, people use this functionality to mark release points (`v1.0`, `v2.0` and so on). +In this section, you'll learn how to list existing tags, how to create and delete tags, and what the different types of tags are. ==== Listing Your Tags -Listing the available tags in Git is straightforward. -Just type `git tag`:(((git commands, tag))) +Listing the existing tags in Git is straightforward. +Just type `git tag` (with optional `-l` or `--list`):(((git commands, tag))) [source,console] ---- $ git tag -v0.1 -v1.3 +v1.0 +v2.0 ---- -This command lists the tags in alphabetical order; the order in which they appear has no real importance. +This command lists the tags in alphabetical order; the order in which they are displayed has no real importance. -You can also search for tags with a particular pattern. +You can also search for tags that match a particular pattern. The Git source repo, for instance, contains more than 500 tags. -If you're only interested in looking at the 1.8.5 series, you can run this: +If you're interested only in looking at the 1.8.5 series, you can run this: [source,console] ---- @@ -39,11 +39,19 @@ v1.8.5.4 v1.8.5.5 ---- +[NOTE] +.Listing tag wildcards requires `-l` or `--list` option +==== +If you want just the entire list of tags, running the command `git tag` implicitly assumes you want a listing and provides one; the use of `-l` or `--list` in this case is optional. + +If, however, you're supplying a wildcard pattern to match tag names, the use of `-l` or `--list` is mandatory. +==== + ==== Creating Tags -Git uses two main types of tags: lightweight and annotated. +Git supports two types of tags: _lightweight_ and _annotated_. -A lightweight tag is very much like a branch that doesn't change – it's just a pointer to a specific commit. +A lightweight tag is very much like a branch that doesn't change -- it's just a pointer to a specific commit. Annotated tags, however, are stored as full objects in the Git database. They're checksummed; contain the tagger name, email, and date; have a tagging message; and can be signed and verified with GNU Privacy Guard (GPG). @@ -92,8 +100,8 @@ That shows the tagger information, the date the commit was tagged, and the annot (((tags, lightweight))) Another way to tag commits is with a lightweight tag. -This is basically the commit checksum stored in a file – no other information is kept. -To create a lightweight tag, don't supply the `-a`, `-s`, or `-m` option: +This is basically the commit checksum stored in a file -- no other information is kept. +To create a lightweight tag, don't supply any of the `-a`, `-s`, or `-m` options, just provide a tag name: [source,console] ---- @@ -179,7 +187,7 @@ Date: Sun Apr 27 20:43:35 2008 -0700 By default, the `git push` command doesn't transfer tags to remote servers.(((git commands, push))) You will have to explicitly push tags to a shared server after you have created them. -This process is just like sharing remote branches – you can run `git push origin [tagname]`. +This process is just like sharing remote branches -- you can run `git push origin `. [source,console] ---- @@ -209,10 +217,71 @@ To git@github.com:schacon/simplegit.git Now, when someone else clones or pulls from your repository, they will get all your tags as well. +[NOTE] +.`git push` pushes both types of tags +==== +Pushing tags using `git push --tags` does not distinguish between lightweight and annotated tags; there is no simple option that allows you to select just one type for pushing. +==== + +==== Deleting Tags + +To delete a tag on your local repository, you can use `git tag -d `. +For example, we could remove our lightweight tag above as follows: + +[source,console] +---- +$ git tag -d v1.4-lw +Deleted tag 'v1.4-lw' (was e7d5add) +---- + +Note that this does not remove the tag from any remote servers. +There are two common variations for deleting a tag from a remote server. + +The first variation is `git push :refs/tags/`: + +[source,console] +---- +$ git push origin :refs/tags/v1.4-lw +To /git@github.com:schacon/simplegit.git + - [deleted] v1.4-lw +---- + +The way to interpret the above is to read it as the null value before the colon is being pushed to the remote tag name, effectively deleting it. + +The second (and more intuitive) way to delete a remote tag is with: + +[source,console] +---- +$ git push origin --delete +---- + ==== Checking out Tags -You can't really check out a tag in Git, since they can't be moved around. -If you want to put a version of your repository in your working directory that looks like a specific tag, you can create a new branch at a specific tag with `git checkout -b [branchname] [tagname]`: +If you want to view the versions of files a tag is pointing to, you can do a `git checkout` of that tag, although this puts your repository in ``detached HEAD'' state, which has some ill side effects: + +[source,console] +---- +$ git checkout 2.0.0 +Note: checking out '2.0.0'. + +You are in 'detached HEAD' state. You can look around, make experimental +changes and commit them, and you can discard any commits you make in this +state without impacting any branches by performing another checkout. + +If you want to create a new branch to retain commits you create, you may +do so (now or later) by using -b with the checkout command again. Example: + + git checkout -b + +HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final + +$ git checkout 2.0-beta-0.1 +Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final +HEAD is now at df3f601... add atlas.json and cover image +---- + +In ``detached HEAD'' state, if you make changes and then create a commit, the tag will stay the same, but your new commit won't belong to any branch and will be unreachable, except by the exact commit hash. +Thus, if you need to make changes -- say you're fixing a bug on an older version, for instance -- you will generally want to create a branch: [source,console] ---- @@ -220,4 +289,4 @@ $ git checkout -b version2 v2.0.0 Switched to a new branch 'version2' ---- -Of course if you do this and do a commit, your `version2` branch will be slightly different than your `v2.0.0` tag since it will move forward with your new changes, so do be careful. +If you do this and make a commit, your `version2` branch will be slightly different than your `v2.0.0` tag since it will move forward with your new changes, so do be careful. diff --git a/book/02-git-basics/sections/undoing.asc b/book/02-git-basics/sections/undoing.asc index da590b23f..e7ad7718a 100644 --- a/book/02-git-basics/sections/undoing.asc +++ b/book/02-git-basics/sections/undoing.asc @@ -1,5 +1,5 @@ [[_undoing]] -=== Undoing Things +=== Ungewollte Änderungen rückgängig machen At any stage, you may want to undo something. Here, we'll review a few basic tools for undoing changes that you've made. @@ -7,7 +7,7 @@ Be careful, because you can't always undo some of these undos. This is one of the few areas in Git where you may lose some work if you do it wrong. One of the common undos takes place when you commit too early and possibly forget to add some files, or you mess up your commit message. -If you want to try that commit again, you can run commit with the `--amend` option: +If you want to redo that commit, make the additional changes you forgot, stage them, and commit again using the `--amend` option: [source,console] ---- @@ -29,7 +29,15 @@ $ git add forgotten_file $ git commit --amend ---- -You end up with a single commit – the second commit replaces the results of the first. +You end up with a single commit -- the second commit replaces the results of the first. + +[NOTE] +==== +It's important to understand that when you're amending your last commit, you're not so much fixing it as _replacing_ it entirely with a new, improved commit that pushes the old commit out of the way and puts the new commit in its place. +Effectively, it's as if the previous commit never happened, and it won't show up in your repository history. + +The obvious value to amending commits is to make minor improvements to your last commit, without cluttering your repository history with commit messages of the form, ``Oops, forgot to add a file'' or ``Darn, fixing a typo in last commit''. +==== [[_unstaging]] ==== Unstaging a Staged File @@ -84,12 +92,12 @@ However, in the scenario described above, the file in your working directory is ===== For now this magic invocation is all you need to know about the `git reset` command. -We'll go into much more detail about what `reset` does and how to master it to do really interesting things in <<_git_reset>>. +We'll go into much more detail about what `reset` does and how to master it to do really interesting things in <>. ==== Unmodifying a Modified File What if you realize that you don't want to keep your changes to the `CONTRIBUTING.md` file? -How can you easily unmodify it – revert it back to what it looked like when you last committed (or initially cloned, or however you got it into your working directory)? +How can you easily unmodify it -- revert it back to what it looked like when you last committed (or initially cloned, or however you got it into your working directory)? Luckily, `git status` tells you how to do that, too. In the last example output, the unstaged area looks like this: @@ -122,12 +130,12 @@ You can see that the changes have been reverted. [IMPORTANT] ===== It's important to understand that `git checkout -- ` is a dangerous command. -Any changes you made to that file are gone – Git just copied another file over it. -Don't ever use this command unless you absolutely know that you don't want the file. +Any local changes you made to that file are gone -- Git just replaced that file with the most recently-committed version. +Don't ever use this command unless you absolutely know that you don't want those unsaved local changes. ===== -If you would like to keep the changes you've made to that file but still need to get it out of the way for now, we'll go over stashing and branching in <<_git_branching>>; these are generally better ways to go. +If you would like to keep the changes you've made to that file but still need to get it out of the way for now, we'll go over stashing and branching in <>; these are generally better ways to go. Remember, anything that is _committed_ in Git can almost always be recovered. -Even commits that were on branches that were deleted or commits that were overwritten with an `--amend` commit can be recovered (see <<_data_recovery>> for data recovery). +Even commits that were on branches that were deleted or commits that were overwritten with an `--amend` commit can be recovered (see <> for data recovery). However, anything you lose that was never committed is likely never to be seen again. diff --git a/book/02-git-basics/sections/viewing-history.asc b/book/02-git-basics/sections/viewing-history.asc index 66be13137..57bb4089a 100644 --- a/book/02-git-basics/sections/viewing-history.asc +++ b/book/02-git-basics/sections/viewing-history.asc @@ -1,18 +1,18 @@ [[_viewing_history]] -=== Viewing the Commit History +=== Anzeigen der Commit-Historie -After you have created several commits, or if you have cloned a repository with an existing commit history, you'll probably want to look back to see what has happened. -The most basic and powerful tool to do this is the `git log` command. +Nachdem Sie mehrere Commits erstellt haben oder wenn Sie ein Repository mit einer bestehenden Commit-Historie geklont haben, werden Sie wahrscheinlich zurückschauen wollen, um zu erfahren, was geschehen ist. +Das wichtigste und mächtigste Werkzeug dafür ist der Befehl `git log`. -These examples use a very simple project called ``simplegit''. -To get the project, run +Diese Beispiele verwenden ein sehr vereinfachtes Projekt namens „simplegit“. +Um das Projekt zu erstellen, führen Sie diesen Befehl aus: [source,console] ---- $ git clone https://github.com/schacon/simplegit-progit ---- -When you run `git log` in this project, you should get output that looks something like this:(((git commands, log))) +Wenn Sie `git log` in diesem Projekt aufrufen, sollten Sie eine Ausgabe erhalten, die ungefähr so aussieht:(((git commands, log))) [source,console] ---- @@ -36,14 +36,14 @@ Date: Sat Mar 15 10:31:28 2008 -0700 first commit ---- -By default, with no arguments, `git log` lists the commits made in that repository in reverse chronological order – that is, the most recent commits show up first. -As you can see, this command lists each commit with its SHA-1 checksum, the author's name and email, the date written, and the commit message. +Standardmäßig listet `git log`, ohne Argumente, die in diesem Repository vorgenommenen Commits in umgekehrter chronologischer Reihenfolge auf, d.h. die neuesten Commits werden als erstes angezeigt. +Wie Sie sehen können, listet dieser Befehl jeden Commit mit seiner SHA-1-Prüfsumme, dem Namen und der E-Mail Adresse des Autors, dem Erstellungs-Datum und der Commit-Beschreibung auf. -A huge number and variety of options to the `git log` command are available to show you exactly what you're looking for. -Here, we'll show you some of the most popular. +Eine Vielzahl und Vielfalt von Optionen für den Befehl `git log` stehen zur Verfügung, um Ihnen exakt das anzuzeigen, wonach Sie gesucht haben. +Hier zeigen wir Ihnen einige der gängigsten. -One of the more helpful options is `-p`, which shows the difference introduced in each commit. -You can also use `-2`, which limits the output to only the last two entries: +Eine der hilfreichsten Optionen ist `-p` oder `--patch`. Sie zeigt den Unterschied (die _patch_-Ausgabe) an, der bei jedem Commit eingefügt wird. +Sie können auch die Anzahl der anzuzeigenden Protokolleinträge begrenzen, z.B. mit `-2` nur die letzten beiden Einträge darstellen. [source,console] ---- @@ -87,13 +87,12 @@ index a0a60ae..47c6340 100644 - git = SimpleGit.new - puts git.show -end -\ No newline at end of file ---- -This option displays the same information but with a diff directly following each entry. -This is very helpful for code review or to quickly browse what happened during a series of commits that a collaborator has added. -You can also use a series of summarizing options with `git log`. -For example, if you want to see some abbreviated stats for each commit, you can use the `--stat` option: +Diese Option zeigt die gleichen Informationen an, jedoch mit dem Unterschied dass sie direkt hinter jedem Eintrag stehen. +Diese Funktion ist sehr hilfreich für die Code-Überprüfung oder zum schnellen Durchsuchen der Vorgänge während einer Reihe von Commits, die ein Teammitglied hinzugefügt hat. +Sie können auch eine Reihe von Optionen zur Verdichtung mit `git log` verwenden. +Wenn Sie beispielsweise einige gekürzte Statistiken für jede Übertragung sehen möchten, können Sie die Option `--stat` verwenden: [source,console] ---- @@ -128,14 +127,14 @@ Date: Sat Mar 15 10:31:28 2008 -0700 3 files changed, 54 insertions(+) ---- -As you can see, the `--stat` option prints below each commit entry a list of modified files, how many files were changed, and how many lines in those files were added and removed. -It also puts a summary of the information at the end. +Wie Sie sehen können, gibt die Option `--stat` unter jedem Commit-Eintrag eine Liste der geänderten Dateien aus. Wie viele Dateien geändert wurden und wie viele Zeilen in diesen Dateien hinzugefügt und entfernt wurden. +Sie enthält auch eine Zusammenfassung am Ende des Berichts. -Another really useful option is `--pretty`. -This option changes the log output to formats other than the default. -A few prebuilt options are available for you to use. -The `oneline` option prints each commit on a single line, which is useful if you're looking at a lot of commits. -In addition, the `short`, `full`, and `fuller` options show the output in roughly the same format but with less or more information, respectively: +Eine weitere wirklich nützliche Option ist `--pretty`. +Diese Option ändert das Format der Log-Ausgabe in ein anderes als das Standard-Format. +Ihnen stehen einige vorgefertigte Optionen zur Verfügung. +Die Option `oneline` druckt jeden Commit in einer einzigen Zeile, was besonders nützlich ist, wenn Sie sich viele Commits ansehen. +Darüber hinaus zeigen die Optionen `short`, `full`, und `fuller` die Ausgabe im etwa gleichen Format, allerdings mit weniger bzw. mehr Informationen: [source,console] ---- @@ -145,8 +144,8 @@ ca82a6dff817ec66f44342007202690a93763949 changed the version number a11bef06a3f659402fe7563abf99ad00de2209e6 first commit ---- -The most interesting option is `format`, which allows you to specify your own log output format. -This is especially useful when you're generating output for machine parsing – because you specify the format explicitly, you know it won't change with updates to Git:(((log formatting))) +Die interessanteste Option ist `format`, mit der Sie Ihr eigenes Log-Ausgabeformat festlegen können. +Dieses Verfahren ist besonders nützlich, wenn Sie Ausgaben für das maschinelle Parsen generieren – da Sie das Format explizit angeben, wissen Sie, dass es sich mit Updates von Git nicht ändert:(((log formatting))) [source,console] ---- @@ -156,37 +155,37 @@ ca82a6d - Scott Chacon, 6 years ago : changed the version number a11bef0 - Scott Chacon, 6 years ago : first commit ---- -<> lists some of the more useful options that `format` takes. +<> listet einige der nützlichsten Optionen auf, die `format` bietet. [[pretty_format]] -.Useful options for `git log --pretty=format` +.Nützliche Optionen für `git log --pretty=format` [cols="1,4",options="header"] |================================ -| Option | Description of Output -| `%H` | Commit hash -| `%h` | Abbreviated commit hash -| `%T` | Tree hash -| `%t` | Abbreviated tree hash -| `%P` | Parent hashes -| `%p` | Abbreviated parent hashes -| `%an` | Author name -| `%ae` | Author email -| `%ad` | Author date (format respects the --date=option) -| `%ar` | Author date, relative -| `%cn` | Committer name -| `%ce` | Committer email -| `%cd` | Committer date -| `%cr` | Committer date, relative -| `%s` | Subject +| Option | Beschreibung der Ausgabe +| `%H` | Commit Hash +| `%h` | gekürzter Commit Hash +| `%T` | Hash-Baum +| `%t` | gekürzter Hash-Baum +| `%P` | Eltern-Hashes +| `%p` | gekürzte Eltern-Hashes +| `%an` | Name des Autors +| `%ae` | E-Mail Adresse des Autors +| `%ad` | Erstellungs-Datum des Autors (Format berücksichtigt --date=option) +| `%ar` | relatives Erstellungs-Datum des Autors +| `%cn` | Name des Committers +| `%ce` | E-Mail Adresse des Committers +| `%cd` | Erstellungs-Datum des Committers +| `%cr` | relatives Erstellungs-Datum des Committers +| `%s` | Thema |================================ -You may be wondering what the difference is between _author_ and _committer_. -The author is the person who originally wrote the work, whereas the committer is the person who last applied the work. -So, if you send in a patch to a project and one of the core members applies the patch, both of you get credit – you as the author, and the core member as the committer. -We'll cover this distinction a bit more in <<_distributed_git>>. +Sie fragen sich vielleicht, worin der Unterschied zwischen _Autor_ und _Committer_ besteht. +Der Autor ist die Person, die das Werk ursprünglich geschrieben hat, während der Committer die Person ist, die das Werk zuletzt bearbeitet hat. +Wenn Sie also einen Patch an ein Projekt senden und eines der Core-Mitglieder den Patch einbindet, erhalten Sie beide die Anerkennung - Sie als Autor und das Core-Mitglied als Committer. +Wir werden diese Unterscheidung näher erläutern in Kapitel 5, <>. -The `oneline` and `format` options are particularly useful with another `log` option called `--graph`. -This option adds a nice little ASCII graph showing your branch and merge history: +Die Optionen `oneline` und `format` sind vor allem bei einer anderen `log`-Option mit Bezeichnung `--graph` hilfreich. +Diese Option fügt ein schönes kleines ASCII-Diagramm hinzu, das Ihren Branch und den Merge-Verlauf zeigt: [source,console] ---- @@ -203,81 +202,89 @@ $ git log --pretty=format:"%h %s" --graph * 11d191e Merge branch 'defunkt' into local ---- -This type of output will become more interesting as we go through branching and merging in the next chapter. +Dieser Ausgabetyp wird immer interessanter, wenn wir im nächsten Kapitel über das Branching und Merging sprechen. -Those are only some simple output-formatting options to `git log` – there are many more. -<> lists the options we've covered so far, as well as some other common formatting options that may be useful, along with how they change the output of the log command. +Das sind nur einige einfache Optionen zur Ausgabe-Formatierung von `git log` – es gibt noch viele mehr. +<> listet die bisher von uns behandelten Optionen auf, sowie einige andere gängige Format-Optionen, die sinnvoll sein können, um die Ausgabe des log-Befehls zu ändern. [[log_options]] -.Common options to `git log` +.Allgemeine Optionen für `git log` [cols="1,4",options="header"] |================================ -| Option | Description -| `-p` | Show the patch introduced with each commit. -| `--stat` | Show statistics for files modified in each commit. -| `--shortstat` | Display only the changed/insertions/deletions line from the --stat command. -| `--name-only` | Show the list of files modified after the commit information. -| `--name-status` | Show the list of files affected with added/modified/deleted information as well. -| `--abbrev-commit` | Show only the first few characters of the SHA-1 checksum instead of all 40. -| `--relative-date` | Display the date in a relative format (for example, ``2 weeks ago'') instead of using the full date format. -| `--graph` | Display an ASCII graph of the branch and merge history beside the log output. -| `--pretty` | Show commits in an alternate format. Options include oneline, short, full, fuller, and format (where you specify your own format). +| Option | Beschreibung +| `-p` | Zeigt den Patch an, der mit den jeweiligen Commits eingefügt wurde. +| `--stat` | Anzeige der Statistiken für Dateien, die in den einzelnen Commits geändert wurden. +| `--shortstat` | Anzeige nur der geänderten/eingefügten/gelöschten Zeile des Befehls --stat. +| `--name-only` | Listet die Dateien auf, die nach den Commit-Informationen geändert wurden. +| `--name-status` | Listet die Dateien auf, die von hinzugefügten, geänderten oder gelöschten Informationen betroffen sind. +| `--abbrev-commit` | Zeigt nur die ersten paar Zeichen der SHA-1-Prüfsumme an, nicht aber alle 40. +| `--relative-date` | Zeigt das Datum in einem relativen Format an (z.B. „vor 2 Wochen“), anstatt das volle Datumsformat zu verwenden. +| `--graph` | Zeigt ein ASCII-Diagramm der Branch an und verbindet die Historie mit der Log-Ausgabe. +| `--pretty` | Zeigt Commits in einem anderen Format an. Zu den Optionen gehören oneline, short, full, fuller und format (womit Sie Ihr eigenes Format angeben können). +| `--oneline` | Kurzform für die gleichzeitige Verwendung von `--pretty=oneline` und `--abbrev-commit`. |================================ -==== Limiting Log Output +==== Einschränken der Log-Ausgabe -In addition to output-formatting options, `git log` takes a number of useful limiting options – that is, options that let you show only a subset of commits. -You've seen one such option already – the `-2` option, which show only the last two commits. -In fact, you can do `-`, where `n` is any integer to show the last `n` commits. -In reality, you're unlikely to use that often, because Git by default pipes all output through a pager so you see only one page of log output at a time. +Zusätzlich zu den Optionen für die Ausgabe-Formatierung bietet `git log` eine Reihe nützlicher einschränkender Optionen, d.h. Optionen, mit denen Sie nur eine Teilmenge von Commits anzeigen können. +Sie haben eine solche Option bereits gesehen – die Option `-2`, die nur die letzten beiden Commits anzeigt. +In Wahrheit können Sie `-` verwenden, wobei `n` eine beliebige ganze Zahl ist, um die letzten `n` Commits anzuzeigen. +In der Praxis werden Sie das kaum verwenden, da Git standardmäßig alle Ausgaben über einen Pager leitet, so dass Sie jeweils nur eine Seite der Log-Ausgabe sehen. -However, the time-limiting options such as `--since` and `--until` are very useful. -For example, this command gets the list of commits made in the last two weeks: +Die zeitbeschränkenden Optionen wie `--since` und `--until` sind sehr nützlich. +Dieser Befehl ruft z.B. die Liste der in den letzten beiden Wochen durchgeführten Commits ab: [source,console] ---- $ git log --since=2.weeks ---- -This command works with lots of formats – you can specify a specific date like `"2008-01-15"`, or a relative date such as `"2 years 1 day 3 minutes ago"`. +Dieser Befehl funktioniert mit vielen Formaten – Sie können ein bestimmtes Datum wie `„2008-01-15“` angeben, oder ein relatives Datum wie `„vor 2 Jahren 1 Tag 3 Minuten“`. -You can also filter the list to commits that match some search criteria. -The `--author` option allows you to filter on a specific author, and the `--grep` option lets you search for keywords in the commit messages. -(Note that if you want to specify both author and grep options, you have to add `--all-match` or the command will match commits with either.) +Sie können die Liste auch nach Commits filtern, die bestimmten Suchkriterien entsprechen. +Mit der Option `--author` können Sie nach einem bestimmten Autoren filtern, und mit der Option `--grep` können Sie nach Schlüsselwörtern in den Übertragungsmeldungen suchen. -Another really helpful filter is the `-S` option which takes a string and only shows the commits that introduced a change to the code that added or removed that string. -For instance, if you wanted to find the last commit that added or removed a reference to a specific function, you could call: +[NOTE] +==== +Sie können mehr als eine Instanz der Suchkriterien `--author` und `--grep` angeben, +was die Commit-Ausgabe auf Commits beschränkt, die _jedem_ der `--author`-Muster und _jedem_ der `--grep`-Muster entsprechen; +durch Hinzufügen der Option `--all-match` wird die Ausgabe jedoch weiter auf diejenigen Commits beschränkt, +die _allen_ `--grep`-Mustern entsprechen. +==== + +Ein weiterer wirklich hilfreicher Filter ist die Option `-S` (umgangssprachlich als Git's „Pickel“-Option bezeichnet), die eine Zeichenkette übernimmt und nur die Commits anzeigt, die die Anzahl der Vorkommen dieses Strings geändert haben. +Wenn Sie beispielsweise das letzte Commit suchen möchten, das einen Verweis auf eine bestimmte Funktion hinzugefügt oder entfernt hat, können Sie Folgendes aufrufen: [source,console] ---- -$ git log -Sfunction_name +$ git log -S function_name ---- -The last really useful option to pass to `git log` as a filter is a path. -If you specify a directory or file name, you can limit the log output to commits that introduced a change to those files. -This is always the last option and is generally preceded by double dashes (`--`) to separate the paths from the options. +Zuletzt eine wirklich nützliche Option, die Sie als Filter an `git log` übergeben können, der Pfad. +Wenn Sie ein Verzeichnis oder einen Dateinamen angeben, können Sie die Log-Ausgabe auf Commits beschränken, die eine Änderung an diesen Dateien vorgenommen haben. +Das ist immer die letzte Option und wird in der Regel durch Doppelstriche (`--`) eingeleitet, um Pfade von den Optionen zu trennen. In <> we'll list these and a few other common options for your reference. [[limit_options]] -.Options to limit the output of `git log` +.Optionen zur Anpassen der Ausgabe von `git log` [cols="2,4",options="header"] |================================ -| Option | Description -| `-(n)` | Show only the last n commits -| `--since`, `--after` | Limit the commits to those made after the specified date. -| `--until`, `--before` | Limit the commits to those made before the specified date. -| `--author` | Only show commits in which the author entry matches the specified string. -| `--committer` | Only show commits in which the committer entry matches the specified string. -| `--grep` | Only show commits with a commit message containing the string -| `-S` | Only show commits adding or removing code matching the string +| Option | Beschreibung +| `-` | Zeigt nur die letzten n Commits an +| `--since`, `--after` | Begrenzt die angezeigten Commits auf die, die nach dem angegebenen Datum gemacht wurden. +| `--until`, `--before` | Begrenzt die angezeigten Commits auf die, die vor dem angegebenen Datum gemacht wurden. +| `--author` | Zeigt nur Commits an, bei denen der Autoren-Eintrag mit der angegebenen Zeichenkette übereinstimmt. +| `--committer` | Zeigt nur Commits an, bei denen der Committer-Eintrag mit der angegebenen Zeichenkette übereinstimmt. +| `--grep` | Zeigt nur Commits an, deren Commit-Beschreibung die Zeichenkette enthält +| `-S` | Zeigt nur Commits an, die solchen Code hinzufügen oder entfernen, der mit der Zeichenkette übereinstimmt |================================ -For example, if you want to see which commits modifying test files in the Git source code history were committed by Junio Hamano in the month of October 2008 and are not merge commits, you can run something like this:(((log filtering))) +Wenn Sie zum Beispiel sehen möchten, welche der Commits, die Testdateien in der Git-Quellcode-Historie ändern, die von Junio Hamano im Monat Oktober 2008 committed wurden und keine Merge-Commits sind, können Sie etwa so aufrufen:(((log filtering))) [source,console] ---- -$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ +$ git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" \ --before="2008-11-01" --no-merges -- t/ 5610e3b - Fix testcase failure when extended attributes are in use acd3b9e - Enhance hold_lock_file_for_{update,append}() API @@ -287,4 +294,11 @@ d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch ---- -Of the nearly 40,000 commits in the Git source code history, this command shows the 6 that match those criteria. +Von den fast 40.000 Commits in der Git-Quellcode-Historie zeigt dieser Befehl die 6 Commits an, die diesen Kriterien entsprechen. + +[TIP] +.Die Anzeige von Merge-Commits unterdrücken +==== +Abhängig von dem in Ihrem Repository verwendeten Workflow ist es möglich, dass ein beträchtlicher Prozentsatz der Commits in Ihrer Log-Historie nur Merge-Commits sind, die in der Regel nicht sehr informativ sind. +Um zu vermeiden, dass die Anzeige von Merge-Commits Ihren Log-Verlauf überflutet, fügen Sie einfach die Log-Option `--no-merges` hinzu. +==== diff --git a/book/03-git-branching/images/advance-master.png b/book/03-git-branching/images/advance-master.png deleted file mode 100644 index c3a7ebe6b..000000000 Binary files a/book/03-git-branching/images/advance-master.png and /dev/null differ diff --git a/book/03-git-branching/images/advance-testing.png b/book/03-git-branching/images/advance-testing.png deleted file mode 100644 index 312e65e15..000000000 Binary files a/book/03-git-branching/images/advance-testing.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-branching-1.png b/book/03-git-branching/images/basic-branching-1.png deleted file mode 100644 index acc3866f2..000000000 Binary files a/book/03-git-branching/images/basic-branching-1.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-branching-2.png b/book/03-git-branching/images/basic-branching-2.png deleted file mode 100644 index c3f149141..000000000 Binary files a/book/03-git-branching/images/basic-branching-2.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-branching-3.png b/book/03-git-branching/images/basic-branching-3.png deleted file mode 100644 index ebc9ca95c..000000000 Binary files a/book/03-git-branching/images/basic-branching-3.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-branching-4.png b/book/03-git-branching/images/basic-branching-4.png deleted file mode 100644 index ab8f22283..000000000 Binary files a/book/03-git-branching/images/basic-branching-4.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-branching-5.png b/book/03-git-branching/images/basic-branching-5.png deleted file mode 100644 index 947133f77..000000000 Binary files a/book/03-git-branching/images/basic-branching-5.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-branching-6.png b/book/03-git-branching/images/basic-branching-6.png deleted file mode 100644 index 6023d6942..000000000 Binary files a/book/03-git-branching/images/basic-branching-6.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-merging-1.png b/book/03-git-branching/images/basic-merging-1.png deleted file mode 100644 index e1bcc27f6..000000000 Binary files a/book/03-git-branching/images/basic-merging-1.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-merging-2.png b/book/03-git-branching/images/basic-merging-2.png deleted file mode 100644 index a24382666..000000000 Binary files a/book/03-git-branching/images/basic-merging-2.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-rebase-1.png b/book/03-git-branching/images/basic-rebase-1.png deleted file mode 100644 index 44ea49e3e..000000000 Binary files a/book/03-git-branching/images/basic-rebase-1.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-rebase-2.png b/book/03-git-branching/images/basic-rebase-2.png deleted file mode 100644 index c82140cdd..000000000 Binary files a/book/03-git-branching/images/basic-rebase-2.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-rebase-3.png b/book/03-git-branching/images/basic-rebase-3.png deleted file mode 100644 index a1afaef66..000000000 Binary files a/book/03-git-branching/images/basic-rebase-3.png and /dev/null differ diff --git a/book/03-git-branching/images/basic-rebase-4.png b/book/03-git-branching/images/basic-rebase-4.png deleted file mode 100644 index e97c1685f..000000000 Binary files a/book/03-git-branching/images/basic-rebase-4.png and /dev/null differ diff --git a/book/03-git-branching/images/branch-and-history.png b/book/03-git-branching/images/branch-and-history.png deleted file mode 100644 index 2b4ab17e6..000000000 Binary files a/book/03-git-branching/images/branch-and-history.png and /dev/null differ diff --git a/book/03-git-branching/images/checkout-master.png b/book/03-git-branching/images/checkout-master.png deleted file mode 100644 index 06e98787c..000000000 Binary files a/book/03-git-branching/images/checkout-master.png and /dev/null differ diff --git a/book/03-git-branching/images/commit-and-tree.png b/book/03-git-branching/images/commit-and-tree.png deleted file mode 100644 index 3ddf1cd5f..000000000 Binary files a/book/03-git-branching/images/commit-and-tree.png and /dev/null differ diff --git a/book/03-git-branching/images/commits-and-parents.png b/book/03-git-branching/images/commits-and-parents.png deleted file mode 100644 index d56397266..000000000 Binary files a/book/03-git-branching/images/commits-and-parents.png and /dev/null differ diff --git a/book/03-git-branching/images/head-to-master.png b/book/03-git-branching/images/head-to-master.png deleted file mode 100644 index 86c7ae858..000000000 Binary files a/book/03-git-branching/images/head-to-master.png and /dev/null differ diff --git a/book/03-git-branching/images/head-to-testing.png b/book/03-git-branching/images/head-to-testing.png deleted file mode 100644 index 08352d608..000000000 Binary files a/book/03-git-branching/images/head-to-testing.png and /dev/null differ diff --git a/book/03-git-branching/images/interesting-rebase-1.png b/book/03-git-branching/images/interesting-rebase-1.png deleted file mode 100644 index ed58a06c0..000000000 Binary files a/book/03-git-branching/images/interesting-rebase-1.png and /dev/null differ diff --git a/book/03-git-branching/images/interesting-rebase-2.png b/book/03-git-branching/images/interesting-rebase-2.png deleted file mode 100644 index 95c306810..000000000 Binary files a/book/03-git-branching/images/interesting-rebase-2.png and /dev/null differ diff --git a/book/03-git-branching/images/interesting-rebase-3.png b/book/03-git-branching/images/interesting-rebase-3.png deleted file mode 100644 index 45aeeca24..000000000 Binary files a/book/03-git-branching/images/interesting-rebase-3.png and /dev/null differ diff --git a/book/03-git-branching/images/interesting-rebase-4.png b/book/03-git-branching/images/interesting-rebase-4.png deleted file mode 100644 index 44b6ca5f3..000000000 Binary files a/book/03-git-branching/images/interesting-rebase-4.png and /dev/null differ diff --git a/book/03-git-branching/images/interesting-rebase-5.png b/book/03-git-branching/images/interesting-rebase-5.png deleted file mode 100644 index aa0745dbe..000000000 Binary files a/book/03-git-branching/images/interesting-rebase-5.png and /dev/null differ diff --git a/book/03-git-branching/images/lr-branches-1.png b/book/03-git-branching/images/lr-branches-1.png deleted file mode 100644 index ad7c9c9a5..000000000 Binary files a/book/03-git-branching/images/lr-branches-1.png and /dev/null differ diff --git a/book/03-git-branching/images/lr-branches-2.png b/book/03-git-branching/images/lr-branches-2.png deleted file mode 100644 index 8db4bc080..000000000 Binary files a/book/03-git-branching/images/lr-branches-2.png and /dev/null differ diff --git a/book/03-git-branching/images/perils-of-rebasing-1.png b/book/03-git-branching/images/perils-of-rebasing-1.png deleted file mode 100644 index 013e04bfe..000000000 Binary files a/book/03-git-branching/images/perils-of-rebasing-1.png and /dev/null differ diff --git a/book/03-git-branching/images/perils-of-rebasing-2.png b/book/03-git-branching/images/perils-of-rebasing-2.png deleted file mode 100644 index 2c14ccdff..000000000 Binary files a/book/03-git-branching/images/perils-of-rebasing-2.png and /dev/null differ diff --git a/book/03-git-branching/images/perils-of-rebasing-3.png b/book/03-git-branching/images/perils-of-rebasing-3.png deleted file mode 100644 index 505407a00..000000000 Binary files a/book/03-git-branching/images/perils-of-rebasing-3.png and /dev/null differ diff --git a/book/03-git-branching/images/perils-of-rebasing-4.png b/book/03-git-branching/images/perils-of-rebasing-4.png deleted file mode 100644 index 01b9dbba3..000000000 Binary files a/book/03-git-branching/images/perils-of-rebasing-4.png and /dev/null differ diff --git a/book/03-git-branching/images/perils-of-rebasing-5.png b/book/03-git-branching/images/perils-of-rebasing-5.png deleted file mode 100644 index 20a189297..000000000 Binary files a/book/03-git-branching/images/perils-of-rebasing-5.png and /dev/null differ diff --git a/book/03-git-branching/images/remote-branches-1.png b/book/03-git-branching/images/remote-branches-1.png deleted file mode 100644 index 759538f46..000000000 Binary files a/book/03-git-branching/images/remote-branches-1.png and /dev/null differ diff --git a/book/03-git-branching/images/remote-branches-2.png b/book/03-git-branching/images/remote-branches-2.png deleted file mode 100644 index 14cfe56c2..000000000 Binary files a/book/03-git-branching/images/remote-branches-2.png and /dev/null differ diff --git a/book/03-git-branching/images/remote-branches-3.png b/book/03-git-branching/images/remote-branches-3.png deleted file mode 100644 index 6d1993e4e..000000000 Binary files a/book/03-git-branching/images/remote-branches-3.png and /dev/null differ diff --git a/book/03-git-branching/images/remote-branches-4.png b/book/03-git-branching/images/remote-branches-4.png deleted file mode 100644 index b4183bf18..000000000 Binary files a/book/03-git-branching/images/remote-branches-4.png and /dev/null differ diff --git a/book/03-git-branching/images/remote-branches-5.png b/book/03-git-branching/images/remote-branches-5.png deleted file mode 100644 index be2282399..000000000 Binary files a/book/03-git-branching/images/remote-branches-5.png and /dev/null differ diff --git a/book/03-git-branching/images/topic-branches-1.png b/book/03-git-branching/images/topic-branches-1.png deleted file mode 100644 index 3bdca0dc1..000000000 Binary files a/book/03-git-branching/images/topic-branches-1.png and /dev/null differ diff --git a/book/03-git-branching/images/topic-branches-2.png b/book/03-git-branching/images/topic-branches-2.png deleted file mode 100644 index fe139d99e..000000000 Binary files a/book/03-git-branching/images/topic-branches-2.png and /dev/null differ diff --git a/book/03-git-branching/images/two-branches.png b/book/03-git-branching/images/two-branches.png deleted file mode 100644 index aa6377a08..000000000 Binary files a/book/03-git-branching/images/two-branches.png and /dev/null differ diff --git a/book/03-git-branching/sections/basic-branching-and-merging.asc b/book/03-git-branching/sections/basic-branching-and-merging.asc index d4494a608..80ec83e19 100644 --- a/book/03-git-branching/sections/basic-branching-and-merging.asc +++ b/book/03-git-branching/sections/basic-branching-and-merging.asc @@ -3,8 +3,8 @@ Let's go through a simple example of branching and merging with a workflow that you might use in the real world. You'll follow these steps: -. Do work on a website. -. Create a branch for a new story you're working on. +. Do some work on a website. +. Create a branch for a new user story you're working on. . Do some work in that branch. At this stage, you'll receive a call that another issue is critical and you need a hotfix. @@ -13,19 +13,19 @@ You'll do the following: . Switch to your production branch. . Create a branch to add the hotfix. . After it's tested, merge the hotfix branch, and push to production. -. Switch back to your original story and continue working. +. Switch back to your original user story and continue working. [[_basic_branching]] ==== Basic Branching (((branches, basic workflow))) -First, let's say you're working on your project and have a couple of commits already. +First, let's say you're working on your project and have a couple of commits already on the `master` branch. .A simple commit history image::images/basic-branching-1.png[A simple commit history.] You've decided that you're going to work on issue #53 in whatever issue-tracking system your company uses. -To create a branch and switch to it at the same time, you can run the `git checkout` command with the `-b` switch: +To create a new branch and switch to it at the same time, you can run the `git checkout` command with the `-b` switch: [source,console] ---- @@ -62,7 +62,7 @@ All you have to do is switch back to your `master` branch. However, before you do that, note that if your working directory or staging area has uncommitted changes that conflict with the branch you're checking out, Git won't let you switch branches. It's best to have a clean working state when you switch branches. -There are ways to get around this (namely, stashing and commit amending) that we'll cover later on, in <<_git_stashing>>. +There are ways to get around this (namely, stashing and commit amending) that we'll cover later on, in <>. For now, let's assume you've committed all your changes, so you can switch back to your `master` branch: [source,console] @@ -76,7 +76,7 @@ This is an important point to remember: when you switch branches, Git resets you It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it. Next, you have a hotfix to make. -Let's create a hotfix branch on which to work until it's completed: +Let's create a `hotfix` branch on which to work until it's completed: [source,console] ---- @@ -91,7 +91,7 @@ $ git commit -a -m 'fixed the broken email address' .Hotfix branch based on `master` image::images/basic-branching-4.png[Hotfix branch based on `master`.] -You can run your tests, make sure the hotfix is what you want, and merge it back into your `master` branch to deploy to production. +You can run your tests, make sure the hotfix is what you want, and finally merge the `hotfix` branch back into your `master` branch to deploy to production. You do this with the `git merge` command:(((git commands, merge))) [source,console] @@ -106,7 +106,7 @@ Fast-forward You'll notice the phrase ``fast-forward'' in that merge. Because the commit `C4` pointed to by the branch `hotfix` you merged in was directly ahead of the commit `C2` you're on, Git simply moves the pointer forward. -To phrase that another way, when you try to merge one commit with a commit that can be reached by following the first commit's history, Git simplifies things by moving the pointer forward because there is no divergent work to merge together – this is called a ``fast-forward.'' +To phrase that another way, when you try to merge one commit with a commit that can be reached by following the first commit's history, Git simplifies things by moving the pointer forward because there is no divergent work to merge together -- this is called a ``fast-forward.'' Your change is now in the snapshot of the commit pointed to by the `master` branch, and you can deploy the fix. @@ -114,7 +114,7 @@ Your change is now in the snapshot of the commit pointed to by the `master` bran image::images/basic-branching-5.png[`master` is fast-forwarded to `hotfix`.] After your super-important fix is deployed, you're ready to switch back to the work you were doing before you were interrupted. -However, first you'll delete the `hotfix` branch, because you no longer need it – the `master` branch points at the same place. +However, first you'll delete the `hotfix` branch, because you no longer need it -- the `master` branch points at the same place. You can delete it with the `-d` option to `git branch`: [source,console] @@ -173,9 +173,6 @@ This is referred to as a merge commit, and is special in that it has more than o .A merge commit image::images/basic-merging-2.png[A merge commit.] -It's worth pointing out that Git determines the best common ancestor to use for its merge base; this is different than older tools like CVS or Subversion (before version 1.5), where the developer doing the merge had to figure out the best merge base for themselves. -This makes merging a heck of a lot easier in Git than in these other systems. - Now that your work is merged in, you have no further need for the `iss53` branch. You can close the ticket in your ticket-tracking system, and delete the branch: @@ -189,8 +186,8 @@ $ git branch -d iss53 (((merging, conflicts))) Occasionally, this process doesn't go smoothly. -If you changed the same part of the same file differently in the two branches you're merging together, Git won't be able to merge them cleanly. -If your fix for issue #53 modified the same part of a file as the `hotfix`, you'll get a merge conflict that looks something like this: +If you changed the same part of the same file differently in the two branches you're merging, Git won't be able to merge them cleanly. +If your fix for issue #53 modified the same part of a file as the `hotfix` branch, you'll get a merge conflict that looks something like this: [source,console] ---- @@ -273,7 +270,7 @@ Just type the name of the tool you'd rather use. [NOTE] ==== -If you need more advanced tools for resolving tricky merge conflicts, we cover more on merging in <<_advanced_merging>>. +If you need more advanced tools for resolving tricky merge conflicts, we cover more on merging in <>. ==== After you exit the merge tool, Git asks you if the merge was successful. diff --git a/book/03-git-branching/sections/branch-management.asc b/book/03-git-branching/sections/branch-management.asc index a8776bb25..3b384babb 100644 --- a/book/03-git-branching/sections/branch-management.asc +++ b/book/03-git-branching/sections/branch-management.asc @@ -59,3 +59,17 @@ If you are sure you want to delete it, run 'git branch -D testing'. ---- If you really do want to delete the branch and lose that work, you can force it with `-D`, as the helpful message points out. + +[TIP] +==== +The options described above, `--merged` and `--no-merged` will, if not given a commit or branch name as an argument, show you what is, respectively, merged or not merged into your _current_ branch. + +You can always provide an additional argument to ask about the merge state with respect to some other branch without checking that other branch out first, as in, what is not merged into the `master` branch? +[source,console] +---- +$ git checkout testing +$ git branch --no-merged master + topicA + featureB +---- +==== diff --git a/book/03-git-branching/sections/nutshell.asc b/book/03-git-branching/sections/nutshell.asc index ff2479cea..88621bbba 100644 --- a/book/03-git-branching/sections/nutshell.asc +++ b/book/03-git-branching/sections/nutshell.asc @@ -3,13 +3,13 @@ To really understand the way Git does branching, we need to take a step back and examine how Git stores its data. -As you may remember from <<_getting_started>>, Git doesn't store data as a series of changesets or differences, but instead as a series of snapshots. +As you may remember from <>, Git doesn't store data as a series of changesets or differences, but instead as a series of _snapshots_. When you make a commit, Git stores a commit object that contains a pointer to the snapshot of the content you staged. -This object also contains the author's name and email, the message that you typed, and pointers to the commit or commits that directly came before this commit (its parent or parents): zero parents for the initial commit, one parent for a normal commit, and multiple parents for a commit that results from a merge of two or more branches. +This object also contains the author's name and email address, the message that you typed, and pointers to the commit or commits that directly came before this commit (its parent or parents): zero parents for the initial commit, one parent for a normal commit, and multiple parents for a commit that results from a merge of two or more branches. To visualize this, let's assume that you have a directory containing three files, and you stage them all and commit. -Staging the files computes a checksum for each one (the SHA-1 hash we mentioned in <<_getting_started>>), stores that version of the file in the Git repository (Git refers to them as blobs), and adds that checksum to the staging area: +Staging the files computes a checksum for each one (the SHA-1 hash we mentioned in <>), stores that version of the file in the Git repository (Git refers to them as _blobs_), and adds that checksum to the staging area: [source,console] ---- @@ -17,10 +17,10 @@ $ git add README test.rb LICENSE $ git commit -m 'The initial commit of my project' ---- -When you create the commit by running `git commit`, Git checksums each subdirectory (in this case, just the root project directory) and stores those tree objects in the Git repository. +When you create the commit by running `git commit`, Git checksums each subdirectory (in this case, just the root project directory) and stores them as a tree object in the Git repository. Git then creates a commit object that has the metadata and a pointer to the root project tree so it can re-create that snapshot when needed.(((git commands, commit))) -Your Git repository now contains five objects: one blob for the contents of each of your three files, one tree that lists the contents of the directory and specifies which file names are stored as which blobs, and one commit with the pointer to that root tree and all the commit metadata. +Your Git repository now contains five objects: three _blobs_ (each representing the contents of one of the three files), one _tree_ that lists the contents of the directory and specifies which file names are stored as which blobs, and one _commit_ with the pointer to that root tree and all the commit metadata. .A commit and its tree image::images/commit-and-tree.png[A commit and its tree.] @@ -33,7 +33,7 @@ image::images/commits-and-parents.png[Commits and their parents.] A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is `master`. As you start making commits, you're given a `master` branch that points to the last commit you made. -Every time you commit, it moves forward automatically. +Every time you commit, the `master` branch pointer moves forward automatically. [NOTE] ==== @@ -49,9 +49,9 @@ image::images/branch-and-history.png[A branch and its commit history.] ==== Creating a New Branch (((branches, creating))) -What happens if you create a new branch? +What happens when you create a new branch? Well, doing so creates a new pointer for you to move around. -Let's say you create a new branch called testing. +Let's say you want to create a new branch called `testing`. You do this with the `git branch` command:(((git commands, branch))) [source,console] @@ -69,7 +69,7 @@ It keeps a special pointer called `HEAD`. Note that this is a lot different than the concept of `HEAD` in other VCSs you may be used to, such as Subversion or CVS. In Git, this is a pointer to the local branch you're currently on. In this case, you're still on `master`. -The `git branch` command only _created_ a new branch – it didn't switch to that branch. +The `git branch` command only _created_ a new branch -- it didn't switch to that branch. .HEAD pointing to a branch image::images/head-to-master.png[HEAD pointing to a branch.] @@ -180,3 +180,9 @@ Also, because we're recording the parents when we commit, finding a proper merge These features help encourage developers to create and use branches often. Let's see why you should do so. + +[NOTE] +.Creating a new branch and switching to it at the same time +==== +It's typical to create a new branch and want to switch to that new branch at the same time -- this can be done in one operation with `git checkout -b `. +==== diff --git a/book/03-git-branching/sections/rebasing.asc b/book/03-git-branching/sections/rebasing.asc index 63c1e68ab..c9e48ede9 100644 --- a/book/03-git-branching/sections/rebasing.asc +++ b/book/03-git-branching/sections/rebasing.asc @@ -15,14 +15,15 @@ image::images/basic-rebase-1.png[Simple divergent history.] The easiest way to integrate the branches, as we've already covered, is the `merge` command. It performs a three-way merge between the two latest branch snapshots (`C3` and `C4`) and the most recent common ancestor of the two (`C2`), creating a new snapshot (and commit). +[[rebasing-merging-example]] .Merging to integrate diverged work history image::images/basic-rebase-2.png[Merging to integrate diverged work history.] However, there is another way: you can take the patch of the change that was introduced in `C4` and reapply it on top of `C3`. In Git, this is called _rebasing_. -With the `rebase` command, you can take all the changes that were committed on one branch and replay them on another one.(((git commands, rebase))) +With the `rebase` command, you can take all the changes that were committed on one branch and replay them on a different branch.(((git commands, rebase))) -In this example, you'd run the following: +For this example, you would check out the `experiment` branch, and then rebase it onto the `master` branch as follows: [source,console] ---- @@ -32,7 +33,7 @@ First, rewinding head to replay your work on top of it... Applying: added staged command ---- -It works by going to the common ancestor of the two branches (the one you're on and the one you're rebasing onto), getting the diff introduced by each commit of the branch you're on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn. +This operation works by going to the common ancestor of the two branches (the one you're on and the one you're rebasing onto), getting the diff introduced by each commit of the branch you're on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn. .Rebasing the change introduced in `C4` onto `C3` image::images/basic-rebase-3.png[Rebasing the change introduced in `C4` onto `C3`.] @@ -48,15 +49,15 @@ $ git merge experiment .Fast-forwarding the master branch image::images/basic-rebase-4.png[Fast-forwarding the master branch.] -Now, the snapshot pointed to by `C4'` is exactly the same as the one that was pointed to by `C5` in the merge example. +Now, the snapshot pointed to by `C4'` is exactly the same as the one that was pointed to by `C5` in <>. There is no difference in the end product of the integration, but rebasing makes for a cleaner history. If you examine the log of a rebased branch, it looks like a linear history: it appears that all the work happened in series, even when it originally happened in parallel. -Often, you'll do this to make sure your commits apply cleanly on a remote branch – perhaps in a project to which you're trying to contribute but that you don't maintain. +Often, you'll do this to make sure your commits apply cleanly on a remote branch -- perhaps in a project to which you're trying to contribute but that you don't maintain. In this case, you'd do your work in a branch and then rebase your work onto `origin/master` when you were ready to submit your patches to the main project. -That way, the maintainer doesn't have to do any integration work – just a fast-forward or a clean apply. +That way, the maintainer doesn't have to do any integration work -- just a fast-forward or a clean apply. -Note that the snapshot pointed to by the final commit you end up with, whether it's the last of the rebased commits for a rebase or the final merge commit after a merge, is the same snapshot – it's only the history that is different. +Note that the snapshot pointed to by the final commit you end up with, whether it's the last of the rebased commits for a rebase or the final merge commit after a merge, is the same snapshot -- it's only the history that is different. Rebasing replays changes from one line of work onto another in the order they were introduced, whereas merging takes the endpoints and merges them together. ==== More Interesting Rebases @@ -98,7 +99,7 @@ $ git merge client image::images/interesting-rebase-3.png[Fast-forwarding your master branch to include the client branch changes.] Let's say you decide to pull in your server branch as well. -You can rebase the server branch onto the `master` branch without having to check it out first by running `git rebase [basebranch] [topicbranch]` – which checks out the topic branch (in this case, `server`) for you and replays it onto the base branch (`master`): +You can rebase the server branch onto the `master` branch without having to check it out first by running `git rebase ` -- which checks out the topic branch (in this case, `server`) for you and replays it onto the base branch (`master`): [source,console] ---- @@ -137,7 +138,7 @@ image::images/interesting-rebase-5.png[Final commit history.] (((rebasing, perils of))) Ahh, but the bliss of rebasing isn't without its drawbacks, which can be summed up in a single line: -*Do not rebase commits that exist outside your repository.* +*Do not rebase commits that exist outside your repository and people may have based work on them.* If you follow that guideline, you'll be fine. If you don't, people will hate you, and you'll be scorned by friends and family. @@ -208,7 +209,8 @@ Or you could do it manually with a `git fetch` followed by a `git rebase teamone If you are using `git pull` and want to make `--rebase` the default, you can set the `pull.rebase` config value with something like `git config --global pull.rebase true`. -If you treat rebasing as a way to clean up and work with commits before you push them, and if you only rebase commits that have never been available publicly, then you'll be fine. +If you only ever rebase commits that have never left your own computer, you'll be just fine. +If you rebase commits that have been pushed, but that no one else has based commits from, you'll also be fine. If you rebase commits that have already been pushed publicly, and people may have based work on those commits, then you may be in for some frustrating trouble, and the scorn of your teammates. If you or a partner does find it necessary at some point, make sure everyone knows to run `git pull --rebase` to try to make the pain after it happens a little bit simpler. diff --git a/book/03-git-branching/sections/remote-branches.asc b/book/03-git-branching/sections/remote-branches.asc index a5c602749..1a81ba1ff 100644 --- a/book/03-git-branching/sections/remote-branches.asc +++ b/book/03-git-branching/sections/remote-branches.asc @@ -7,12 +7,12 @@ You can get a full list of remote references explicitly with `git ls-remote [rem Nevertheless, a more common way is to take advantage of remote-tracking branches. Remote-tracking branches are references to the state of remote branches. -They're local references that you can't move; they're moved automatically for you whenever you do any network communication. -Remote-tracking branches act as bookmarks to remind you where the branches in your remote repositories were the last time you connected to them. +They're local references that you can't move; Git moves them for you whenever you do any network communication, to make sure they accurately represent the state of the remote repository. +Think of them as bookmarks, to remind you where the branches in your remote repositories were the last time you connected to them. -They take the form `(remote)/(branch)`. +Remote-tracking branch names take the form `/`. For instance, if you wanted to see what the `master` branch on your `origin` remote looked like as of the last time you communicated with it, you would check the `origin/master` branch. -If you were working on an issue with a partner and they pushed up an `iss53` branch, you might have your own local `iss53` branch; but the branch on the server would point to the commit at `origin/iss53`. +If you were working on an issue with a partner and they pushed up an `iss53` branch, you might have your own local `iss53` branch, but the branch on the server would be represented by the remote-tracking branch `origin/iss53`. This may be a bit confusing, so let's look at an example. Let's say you have a Git server on your network at `git.ourcompany.com`. @@ -36,15 +36,15 @@ Also, as long as you stay out of contact with your origin server, your `origin/m .Local and remote work can diverge image::images/remote-branches-2.png[Local and remote work can diverge.] -To synchronize your work, you run a `git fetch origin` command. +To synchronize your work with a given remote, you run a `git fetch ` command (in our case, `git fetch origin`). This command looks up which server ``origin'' is (in this case, it's `git.ourcompany.com`), fetches any data from it that you don't yet have, and updates your local database, moving your `origin/master` pointer to its new, more up-to-date position. -.`git fetch` updates your remote references +.`git fetch` updates your remote-tracking branches image::images/remote-branches-3.png[`git fetch` updates your remote references.] To demonstrate having multiple remote servers and what remote branches for those remote projects look like, let's assume you have another internal Git server that is used only for development by one of your sprint teams. This server is at `git.team1.ourcompany.com`. -You can add it as a new remote reference to the project you're currently working on by running the `git remote add` command as we covered in <<_git_basics_chapter>>. +You can add it as a new remote reference to the project you're currently working on by running the `git remote add` command as we covered in <>. Name this remote `teamone`, which will be your shortname for that whole URL. .Adding another server as a remote @@ -53,15 +53,15 @@ image::images/remote-branches-4.png[Adding another server as a remote.] Now, you can run `git fetch teamone` to fetch everything the remote `teamone` server has that you don't have yet. Because that server has a subset of the data your `origin` server has right now, Git fetches no data but sets a remote-tracking branch called `teamone/master` to point to the commit that `teamone` has as its `master` branch. -.Remote tracking branch for `teamone/master` +.Remote-tracking branch for `teamone/master` image::images/remote-branches-5.png[Remote tracking branch for `teamone/master`.] [[_pushing_branches]] ==== Pushing (((pushing))) -When you want to share a branch with the world, you need to push it up to a remote that you have write access to. -Your local branches aren't automatically synchronized to the remotes you write to – you have to explicitly push the branches you want to share. +When you want to share a branch with the world, you need to push it up to a remote to which you have write access. +Your local branches aren't automatically synchronized to the remotes you write to -- you have to explicitly push the branches you want to share. That way, you can use private branches for work you don't want to share, and push up only the topic branches you want to collaborate on. If you have a branch named `serverfix` that you want to work on with others, you can push it up the same way you pushed your first branch. @@ -81,8 +81,8 @@ To https://github.com/schacon/simplegit This is a bit of a shortcut. Git automatically expands the `serverfix` branchname out to `refs/heads/serverfix:refs/heads/serverfix`, which means, ``Take my serverfix local branch and push it to update the remote's serverfix branch.'' -We'll go over the `refs/heads/` part in detail in <<_git_internals>>, but you can generally leave it off. -You can also do `git push origin serverfix:serverfix`, which does the same thing – it says, ``Take my serverfix and make it the remote's serverfix.'' +We'll go over the `refs/heads/` part in detail in <>, but you can generally leave it off. +You can also do `git push origin serverfix:serverfix`, which does the same thing -- it says, ``Take my serverfix and make it the remote's serverfix.'' You can use this format to push a local branch into a remote branch that is named differently. If you didn't want it to be called `serverfix` on the remote, you could instead run `git push origin serverfix:awesomebranch` to push your local `serverfix` branch to the `awesomebranch` branch on the remote project. @@ -95,7 +95,7 @@ By default it will prompt you on the terminal for this information so the server If you don't want to type it every single time you push, you can set up a ``credential cache''. The simplest is just to keep it in memory for a few minutes, which you can easily set up by running `git config --global credential.helper cache`. -For more information on the various credential caching options available, see <<_credential_caching>>. +For more information on the various credential caching options available, see <>. ==== The next time one of your collaborators fetches from the server, they will get a reference to where the server's version of `serverfix` is under the remote branch `origin/serverfix`: @@ -112,7 +112,7 @@ From https://github.com/schacon/simplegit ---- It's important to note that when you do a fetch that brings down new remote-tracking branches, you don't automatically have local, editable copies of them. -In other words, in this case, you don't have a new `serverfix` branch – you only have an `origin/serverfix` pointer that you can't modify. +In other words, in this case, you don't have a new `serverfix` branch -- you have only an `origin/serverfix` pointer that you can't modify. To merge this work into your current working branch, you can run `git merge origin/serverfix`. If you want your own `serverfix` branch that you can work on, you can base it off your remote-tracking branch: @@ -132,11 +132,11 @@ This gives you a local branch that you can work on that starts where `origin/ser (((branches, tracking)))(((branches, upstream))) Checking out a local branch from a remote-tracking branch automatically creates what is called a ``tracking branch'' (and the branch it tracks is called an ``upstream branch''). Tracking branches are local branches that have a direct relationship to a remote branch. -If you're on a tracking branch and type `git pull`, Git automatically knows which server to fetch from and branch to merge into. +If you're on a tracking branch and type `git pull`, Git automatically knows which server to fetch from and which branch to merge in. When you clone a repository, it generally automatically creates a `master` branch that tracks `origin/master`. -However, you can set up other tracking branches if you wish – ones that track branches on other remotes, or don't track the `master` branch. -The simple case is the example you just saw, running `git checkout -b [branch] [remotename]/[branch]`. +However, you can set up other tracking branches if you wish -- ones that track branches on other remotes, or don't track the `master` branch. +The simple case is the example you just saw, running `git checkout -b /`. This is a common enough operation that Git provides the `--track` shorthand: [source,console] @@ -146,7 +146,8 @@ Branch serverfix set up to track remote branch serverfix from origin. Switched to a new branch 'serverfix' ---- -In fact, this is so common that there's even a shortcut for that shortcut. If the branch name you're trying to checkout (a) doesn't exist and (b) exactly matches a name on only one remote, Git will create a tracking branch for you: +In fact, this is so common that there's even a shortcut for that shortcut. +If the branch name you're trying to checkout (a) doesn't exist and (b) exactly matches a name on only one remote, Git will create a tracking branch for you: [source,console] ---- @@ -211,7 +212,7 @@ $ git fetch --all; git branch -vv ==== Pulling (((pulling))) -While the `git fetch` command will fetch down all the changes on the server that you don't have yet, it will not modify your working directory at all. +While the `git fetch` command will fetch all the changes on the server that you don't have yet, it will not modify your working directory at all. It will simply get the data for you and let you merge it yourself. However, there is a command called `git pull` which is essentially a `git fetch` immediately followed by a `git merge` in most cases. If you have a tracking branch set up as demonstrated in the last section, either by explicitly setting it or by having it created for you by the `clone` or `checkout` commands, `git pull` will look up what server and branch your current branch is tracking, fetch from that server and then try to merge in that remote branch. @@ -222,7 +223,7 @@ Generally it's better to simply use the `fetch` and `merge` commands explicitly ==== Deleting Remote Branches (((branches, deleting remote))) -Suppose you're done with a remote branch – say you and your collaborators are finished with a feature and have merged it into your remote's `master` branch (or whatever branch your stable codeline is in). +Suppose you're done with a remote branch -- say you and your collaborators are finished with a feature and have merged it into your remote's `master` branch (or whatever branch your stable codeline is in). You can delete a remote branch using the `--delete` option to `git push`. If you want to delete your `serverfix` branch from the server, you run the following: diff --git a/book/03-git-branching/sections/workflows.asc b/book/03-git-branching/sections/workflows.asc index 1116789eb..4ae66a76d 100644 --- a/book/03-git-branching/sections/workflows.asc +++ b/book/03-git-branching/sections/workflows.asc @@ -1,7 +1,7 @@ === Branching Workflows Now that you have the basics of branching and merging down, what can or should you do with them? -In this section, we'll cover some common workflows that this lightweight branching makes possible, so you can decide if you would like to incorporate it into your own development cycle. +In this section, we'll cover some common workflows that this lightweight branching makes possible, so you can decide if you would like to incorporate them into your own development cycle. ==== Long-Running Branches @@ -9,8 +9,8 @@ In this section, we'll cover some common workflows that this lightweight branchi Because Git uses a simple three-way merge, merging from one branch into another multiple times over a long period is generally easy to do. This means you can have several branches that are always open and that you use for different stages of your development cycle; you can merge regularly from some of them into others. -Many Git developers have a workflow that embraces this approach, such as having only code that is entirely stable in their `master` branch – possibly only code that has been or will be released. -They have another parallel branch named `develop` or `next` that they work from or use to test stability – it isn't necessarily always stable, but whenever it gets to a stable state, it can be merged into `master`. +Many Git developers have a workflow that embraces this approach, such as having only code that is entirely stable in their `master` branch -- possibly only code that has been or will be released. +They have another parallel branch named `develop` or `next` that they work from or use to test stability -- it isn't necessarily always stable, but whenever it gets to a stable state, it can be merged into `master`. It's used to pull in topic branches (short-lived branches, like your earlier `iss53` branch) when they're ready, to make sure they pass all the tests and don't introduce bugs. In reality, we're talking about pointers moving up the line of commits you're making. @@ -41,7 +41,7 @@ But in Git it's common to create, work on, merge, and delete branches several ti You saw this in the last section with the `iss53` and `hotfix` branches you created. You did a few commits on them and deleted them directly after merging them into your main branch. -This technique allows you to context-switch quickly and completely – because your work is separated into silos where all the changes in that branch have to do with that topic, it's easier to see what has happened during code review and such. +This technique allows you to context-switch quickly and completely -- because your work is separated into silos where all the changes in that branch have to do with that topic, it's easier to see what has happened during code review and such. You can keep the changes there for minutes, days, or months, and merge them in when they're ready, regardless of the order in which they were created or worked on. Consider an example of doing some work (on `master`), branching off for an issue (`iss91`), working on it for a bit, branching off the second branch to try another way of handling the same thing (`iss91v2`), going back to your `master` branch and working there for a while, and then branching off there to do some work that you're not sure is a good idea (`dumbidea` branch). @@ -57,7 +57,7 @@ Your history then looks like this: .History after merging `dumbidea` and `iss91v2` image::images/topic-branches-2.png[History after merging `dumbidea` and `iss91v2`.] -We will go into more detail about the various possible workflows for your Git project in <<_distributed_git>>, so before you decide which branching scheme your next project will use, be sure to read that chapter. +We will go into more detail about the various possible workflows for your Git project in <>, so before you decide which branching scheme your next project will use, be sure to read that chapter. It's important to remember when you're doing all this that these branches are completely local. -When you're branching and merging, everything is being done only in your Git repository – no server communication is happening. +When you're branching and merging, everything is being done only in your Git repository -- there is no communication with the server. diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc deleted file mode 100644 index 8e6ae12d4..000000000 --- a/book/04-git-server/1-git-server.asc +++ /dev/null @@ -1,47 +0,0 @@ -== Git on the Server - -(((serving repositories))) -At this point, you should be able to do most of the day-to-day tasks for which you'll be using Git. -However, in order to do any collaboration in Git, you'll need to have a remote Git repository. -Although you can technically push changes to and pull changes from individuals' repositories, doing so is discouraged because you can fairly easily confuse what they're working on if you're not careful. -Furthermore, you want your collaborators to be able to access the repository even if your computer is offline – having a more reliable common repository is often useful. -Therefore, the preferred method for collaborating with someone is to set up an intermediate repository that you both have access to, and push to and pull from that. - -Running a Git server is fairly straightforward. -First, you choose which protocols you want your server to communicate with. -The first section of this chapter will cover the available protocols and the pros and cons of each. -The next sections will explain some typical setups using those protocols and how to get your server running with them. -Last, we'll go over a few hosted options, if you don't mind hosting your code on someone else's server and don't want to go through the hassle of setting up and maintaining your own server. - -If you have no interest in running your own server, you can skip to the last section of the chapter to see some options for setting up a hosted account and then move on to the next chapter, where we discuss the various ins and outs of working in a distributed source control environment. - -A remote repository is generally a _bare repository_ – a Git repository that has no working directory. -Because the repository is only used as a collaboration point, there is no reason to have a snapshot checked out on disk; it's just the Git data. -In the simplest terms, a bare repository is the contents of your project's `.git` directory and nothing else. - -include::sections/protocols.asc[] - -include::sections/git-on-a-server.asc[] - -include::sections/generating-ssh-key.asc[] - -include::sections/setting-up-server.asc[] - -include::sections/git-daemon.asc[] - -include::sections/smart-http.asc[] - -include::sections/gitweb.asc[] - -include::sections/gitlab.asc[] - -include::sections/hosted.asc[] - -=== Summary - -You have several options to get a remote Git repository up and running so that you can collaborate with others or share your work. - -Running your own server gives you a lot of control and allows you to run the server within your own firewall, but such a server generally requires a fair amount of your time to set up and maintain. -If you place your data on a hosted server, it's easy to set up and maintain; however, you have to be able to keep your code on someone else's servers, and some organizations don't allow that. - -It should be fairly straightforward to determine which solution or combination of solutions is appropriate for you and your organization. diff --git a/book/04-git-server/images/gitlab-broadcast.png b/book/04-git-server/images/gitlab-broadcast.png deleted file mode 100644 index 8d3f690d4..000000000 Binary files a/book/04-git-server/images/gitlab-broadcast.png and /dev/null differ diff --git a/book/04-git-server/images/gitlab-groups.png b/book/04-git-server/images/gitlab-groups.png deleted file mode 100644 index 399c5e62c..000000000 Binary files a/book/04-git-server/images/gitlab-groups.png and /dev/null differ diff --git a/book/04-git-server/images/gitlab-menu.png b/book/04-git-server/images/gitlab-menu.png deleted file mode 100644 index beed44978..000000000 Binary files a/book/04-git-server/images/gitlab-menu.png and /dev/null differ diff --git a/book/04-git-server/images/gitlab-users.png b/book/04-git-server/images/gitlab-users.png deleted file mode 100644 index e2edb586f..000000000 Binary files a/book/04-git-server/images/gitlab-users.png and /dev/null differ diff --git a/book/04-git-server/sections/generating-ssh-key.asc b/book/04-git-server/sections/generating-ssh-key.asc index 8dbf7291c..6ed59b1f3 100644 --- a/book/04-git-server/sections/generating-ssh-key.asc +++ b/book/04-git-server/sections/generating-ssh-key.asc @@ -2,7 +2,7 @@ === Generating Your SSH Public Key (((SSH keys))) -That being said, many Git servers authenticate using SSH public keys. +Many Git servers authenticate using SSH public keys. In order to provide a public key, each user in your system must generate one if they don't already have one. This process is similar across all operating systems. First, you should check to make sure you don't already have a key. @@ -18,12 +18,12 @@ config id_dsa.pub ---- You're looking for a pair of files named something like `id_dsa` or `id_rsa` and a matching file with a `.pub` extension. -The `.pub` file is your public key, and the other file is your private key. -If you don't have these files (or you don't even have a `.ssh` directory), you can create them by running a program called `ssh-keygen`, which is provided with the SSH package on Linux/Mac systems and comes with Git for Windows: +The `.pub` file is your public key, and the other file is the corresponding private key. +If you don't have these files (or you don't even have a `.ssh` directory), you can create them by running a program called `ssh-keygen`, which is provided with the SSH package on Linux/macOS systems and comes with Git for Windows: [source,console] ---- -$ ssh-keygen +$ ssh-keygen -o Generating public/private rsa key pair. Enter file in which to save the key (/home/schacon/.ssh/id_rsa): Created directory '/home/schacon/.ssh'. @@ -36,6 +36,8 @@ d0:82:24:8e:d7:f1:bb:9b:33:53:96:93:49:da:9b:e3 schacon@mylaptop.local ---- First it confirms where you want to save the key (`.ssh/id_rsa`), and then it asks twice for a passphrase, which you can leave empty if you don't want to type a password when you use the key. +However, if you do use a password, make sure to add the `-o` option; it saves the private key in a format that is more resistant to brute-force password cracking than is the default format. +You can also use the `ssh-agent` tool to prevent having to enter the password each time. Now, each user that does this has to send their public key to you or whoever is administrating the Git server (assuming you're using an SSH server setup that requires public keys). All they have to do is copy the contents of the `.pub` file and email it. diff --git a/book/04-git-server/sections/git-daemon.asc b/book/04-git-server/sections/git-daemon.asc index c5332a494..1bc425770 100644 --- a/book/04-git-server/sections/git-daemon.asc +++ b/book/04-git-server/sections/git-daemon.asc @@ -1,11 +1,11 @@ === Git Daemon (((serving repositories, git protocol))) -Next we'll set up a daemon serving repositories over the ``Git'' protocol. -This is common choice for fast, unauthenticated access to your Git data. -Remember that since it's not an authenticated service, anything you serve over this protocol is public within its network. +Next we'll set up a daemon serving repositories using the ``Git'' protocol. +This is a common choice for fast, unauthenticated access to your Git data. +Remember that since this is not an authenticated service, anything you serve over this protocol is public within its network. -If you're running this on a server outside your firewall, it should only be used for projects that are publicly visible to the world. +If you're running this on a server outside your firewall, it should be used only for projects that are publicly visible to the world. If the server you're running it on is inside your firewall, you might use it for projects that a large number of people or computers (continuous integration or build servers) have read-only access to, when you don't want to have to add an SSH key for each. In any case, the Git protocol is relatively easy to set up. @@ -16,44 +16,43 @@ Basically, you need to run this command in a daemonized manner:(((git commands, $ git daemon --reuseaddr --base-path=/srv/git/ /srv/git/ ---- -`--reuseaddr` allows the server to restart without waiting for old connections to time out, the `--base-path` option allows people to clone projects without specifying the entire path, and the path at the end tells the Git daemon where to look for repositories to export. +The `--reuseaddr` option allows the server to restart without waiting for old connections to time out, while the `--base-path` option allows people to clone projects without specifying the entire path, and the path at the end tells the Git daemon where to look for repositories to export. If you're running a firewall, you'll also need to punch a hole in it at port 9418 on the box you're setting this up on. You can daemonize this process a number of ways, depending on the operating system you're running. -On an Ubuntu machine, you can use an Upstart script. -So, in the following file + +Since `systemd` is the most common init system among modern Linux distributions, you can use it for that purpose. +Simply place a file in `/etc/systemd/system/git-daemon.service` with these contents: [source,console] ---- -/etc/init/local-git-daemon.conf ----- +[Unit] +Description=Start Git Daemon -you put this script: +[Service] +ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/srv/git/ /srv/git/ -[source,console] ----- -start on startup -stop on shutdown -exec /usr/bin/git daemon \ - --user=git --group=git \ - --reuseaddr \ - --base-path=/srv/git/ \ - /srv/git/ -respawn ----- +Restart=always +RestartSec=500ms -For security reasons, it is strongly encouraged to have this daemon run as a user with read-only permissions to the repositories – you can easily do this by creating a new user 'git-ro' and running the daemon as them. -For the sake of simplicity we'll simply run it as the same 'git' user that `git-shell` is running as. +StandardOutput=syslog +StandardError=syslog +SyslogIdentifier=git-daemon -When you restart your machine, your Git daemon will start automatically and respawn if it goes down. -To get it running without having to reboot, you can run this: +User=git +Group=git -[source,console] ----- -$ initctl start local-git-daemon +[Install] +WantedBy=multi-user.target ---- -On other systems, you may want to use `xinetd`, a script in your `sysvinit` system, or something else – as long as you get that command daemonized and watched somehow. +You might have noticed that Git daemon is started here with `git` as both group and user. +Modify it to fit your needs and make sure the provided user exists on the system. +Also, check that the Git binary is indeed located at `/usr/bin/git` and change the path if necessary. + +Finally, you'll run `systemctl enable git-daemon` to automatically start the service on boot, and can start and stop the service with, respectively, `systemctl start git-daemon` and `systemctl stop git-daemon`. + +On other systems, you may want to use `xinetd`, a script in your `sysvinit` system, or something else -- as long as you get that command daemonized and watched somehow. Next, you have to tell Git which repositories to allow unauthenticated Git server-based access to. You can do this in each repository by creating a file named `git-daemon-export-ok`. diff --git a/book/04-git-server/sections/git-on-a-server.asc b/book/04-git-server/sections/git-on-a-server.asc index ac006f15f..18727c660 100644 --- a/book/04-git-server/sections/git-on-a-server.asc +++ b/book/04-git-server/sections/git-on-a-server.asc @@ -1,18 +1,18 @@ -[[_git_on_the_server]] +[[_getting_git_on_a_server]] === Getting Git on a Server Now we'll cover setting up a Git service running these protocols on your own server. [NOTE] ==== -Here we'll be demonstrating the commands and steps needed to do basic, simplified installations on a Linux based server, though it's also possible to run these services on Mac or Windows servers. +Here we'll be demonstrating the commands and steps needed to do basic, simplified installations on a Linux-based server, though it's also possible to run these services on macOS or Windows servers. Actually setting up a production server within your infrastructure will certainly entail differences in security measures or operating system tools, but hopefully this will give you the general idea of what's involved. ==== -In order to initially set up any Git server, you have to export an existing repository into a new bare repository – a repository that doesn't contain a working directory. +In order to initially set up any Git server, you have to export an existing repository into a new bare repository -- a repository that doesn't contain a working directory. This is generally straightforward to do. In order to clone your repository to create a new bare repository, you run the clone command with the `--bare` option.(((git commands, clone, bare))) -By convention, bare repository directories end in `.git`, like so: +By convention, bare repository directory names end with the suffix `.git`, like so: [source,console] ---- @@ -30,14 +30,14 @@ This is roughly equivalent to something like $ cp -Rf my_project/.git my_project.git ---- -There are a couple of minor differences in the configuration file; but for your purpose, this is close to the same thing. +There are a couple of minor differences in the configuration file but, for your purpose, this is close to the same thing. It takes the Git repository by itself, without a working directory, and creates a directory specifically for it alone. [[_bare_repo]] ==== Putting the Bare Repository on a Server Now that you have a bare copy of your repository, all you need to do is put it on a server and set up your protocols. -Let's say you've set up a server called `git.example.com` that you have SSH access to, and you want to store all your Git repositories under the `/srv/git` directory. +Let's say you've set up a server called `git.example.com` to which you have SSH access, and you want to store all your Git repositories under the `/srv/git` directory. Assuming that `/srv/git` exists on that server, you can set up your new repository by copying your bare repository over: [source,console] @@ -45,7 +45,7 @@ Assuming that `/srv/git` exists on that server, you can set up your new reposito $ scp -r my_project.git user@git.example.com:/srv/git ---- -At this point, other users who have SSH access to the same server which has read-access to the `/srv/git` directory can clone your repository by running +At this point, other users who have SSH-based read access to the `/srv/git` directory on that server can clone your repository by running [source,console] ---- @@ -54,7 +54,8 @@ $ git clone user@git.example.com:/srv/git/my_project.git If a user SSHs into a server and has write access to the `/srv/git/my_project.git` directory, they will also automatically have push access. -Git will automatically add group write permissions to a repository properly if you run the `git init` command with the `--shared` option.(((git commands, init, bare))) +Git will automatically add group write permissions to a repository properly if you run the `git init` command with the `--shared` option. +Note that by running this command, you will not destroy any commits, refs, etc. in the process.(((git commands, init, bare))) [source,console] ---- @@ -66,8 +67,8 @@ $ git init --bare --shared You see how easy it is to take a Git repository, create a bare version, and place it on a server to which you and your collaborators have SSH access. Now you're ready to collaborate on the same project. -It's important to note that this is literally all you need to do to run a useful Git server to which several people have access – just add SSH-able accounts on a server, and stick a bare repository somewhere that all those users have read and write access to. -You're ready to go – nothing else needed. +It's important to note that this is literally all you need to do to run a useful Git server to which several people have access -- just add SSH-able accounts on a server, and stick a bare repository somewhere that all those users have read and write access to. +You're ready to go -- nothing else needed. In the next few sections, you'll see how to expand to more sophisticated setups. This discussion will include not having to create user accounts for each user, adding public read access to repositories, setting up web UIs and more. @@ -77,24 +78,24 @@ However, keep in mind that to collaborate with a couple of people on a private p If you're a small outfit or are just trying out Git in your organization and have only a few developers, things can be simple for you. One of the most complicated aspects of setting up a Git server is user management. -If you want some repositories to be read-only to certain users and read/write to others, access and permissions can be a bit more difficult to arrange. +If you want some repositories to be read-only for certain users and read/write for others, access and permissions can be a bit more difficult to arrange. ===== SSH Access (((serving repositories, SSH))) If you have a server to which all your developers already have SSH access, it's generally easiest to set up your first repository there, because you have to do almost no work (as we covered in the last section). -If you want more complex access control type permissions on your repositories, you can handle them with the normal filesystem permissions of the operating system your server runs. +If you want more complex access control type permissions on your repositories, you can handle them with the normal filesystem permissions of your server's operating system. -If you want to place your repositories on a server that doesn't have accounts for everyone on your team whom you want to have write access, then you must set up SSH access for them. +If you want to place your repositories on a server that doesn't have accounts for everyone on your team for whom you want to grant write access, then you must set up SSH access for them. We assume that if you have a server with which to do this, you already have an SSH server installed, and that's how you're accessing the server. There are a few ways you can give access to everyone on your team. The first is to set up accounts for everybody, which is straightforward but can be cumbersome. -You may not want to run `adduser` and set temporary passwords for every user. +You may not want to run `adduser` (or the possible alternative `useradd`) and have to set temporary passwords for every new user. -A second method is to create a single 'git' user on the machine, ask every user who is to have write access to send you an SSH public key, and add that key to the `~/.ssh/authorized_keys` file of your new 'git' user. -At that point, everyone will be able to access that machine via the 'git' user. -This doesn't affect the commit data in any way – the SSH user you connect as doesn't affect the commits you've recorded. +A second method is to create a single 'git' user account on the machine, ask every user who is to have write access to send you an SSH public key, and add that key to the `~/.ssh/authorized_keys` file of that new 'git' account. +At that point, everyone will be able to access that machine via the 'git' account. +This doesn't affect the commit data in any way -- the SSH user you connect as doesn't affect the commits you've recorded. Another way to do it is to have your SSH server authenticate from an LDAP server or some other centralized authentication source that you may already have set up. As long as each user can get shell access on the machine, any SSH authentication mechanism you can think of should work. diff --git a/book/04-git-server/sections/gitlab.asc b/book/04-git-server/sections/gitlab.asc index fbec2a910..a17d0e5d0 100644 --- a/book/04-git-server/sections/gitlab.asc +++ b/book/04-git-server/sections/gitlab.asc @@ -13,7 +13,7 @@ Fortunately, this process is very well-documented and supported. There are a few methods you can pursue to install GitLab. To get something up and running quickly, you can download a virtual machine image or a one-click installer from https://bitnami.com/stack/gitlab[], and tweak the configuration to match your particular environment.(((bitnami))) -One nice touch Bitnami has included is the login screen (accessed by typing alt-→); it tells you the IP address and default username and password for the installed GitLab. +One nice touch Bitnami has included is the login screen (accessed by typing alt+→); it tells you the IP address and default username and password for the installed GitLab. [[bitnami]] .The Bitnami GitLab virtual machine login screen. @@ -39,7 +39,7 @@ image::images/gitlab-menu.png[The ``Admin area'' item in the GitLab menu.] Users in GitLab are accounts that correspond to people. User accounts don't have a lot of complexity; mainly it's a collection of personal information attached to login data. Each user account comes with a *namespace*, which is a logical grouping of projects that belong to that user. -If the user +jane+ had a project named +project+, that project's url would be http://server/jane/project[]. +If the user +jane+ had a project named +project+, that project's url would be `http://server/jane/project`. [[gitlab_users]] .The GitLab user administration screen. @@ -56,7 +56,7 @@ This is obviously a much more permanent and destructive action, and its uses are ===== Groups A GitLab group is an assemblage of projects, along with data about how users can access those projects. -Each group has a project namespace (the same way that users do), so if the group +training+ has a project +materials+, its url would be http://server/training/materials[]. +Each group has a project namespace (the same way that users do), so if the group +training+ has a project +materials+, its url would be `http://server/training/materials`. [[gitlab_groups]] .The GitLab group administration screen. diff --git a/book/04-git-server/sections/gitweb.asc b/book/04-git-server/sections/gitweb.asc index a12a6d36c..b0c4572df 100644 --- a/book/04-git-server/sections/gitweb.asc +++ b/book/04-git-server/sections/gitweb.asc @@ -8,7 +8,7 @@ Git comes with a CGI script called GitWeb that is sometimes used for this. .The GitWeb web-based user interface. image::images/git-instaweb.png[The GitWeb web-based user interface.] -If you want to check out what GitWeb would look like for your project, Git comes with a command to fire up a temporary instance if you have a lightweight server on your system like `lighttpd` or `webrick`. +If you want to check out what GitWeb would look like for your project, Git comes with a command to fire up a temporary instance if you have a lightweight web server on your system like `lighttpd` or `webrick`. On Linux machines, `lighttpd` is often installed, so you may be able to get it to run by typing `git instaweb` in your project directory. If you're running a Mac, Leopard comes preinstalled with Ruby, so `webrick` may be your best bet. To start `instaweb` with a non-lighttpd handler, you can run it with the `--httpd` option.(((git commands, instaweb))) @@ -30,7 +30,7 @@ $ git instaweb --httpd=webrick --stop ---- If you want to run the web interface on a server all the time for your team or for an open source project you're hosting, you'll need to set up the CGI script to be served by your normal web server. -Some Linux distributions have a `gitweb` package that you may be able to install via `apt` or `yum`, so you may want to try that first. +Some Linux distributions have a `gitweb` package that you may be able to install via `apt` or `dnf`, so you may want to try that first. We'll walk through installing GitWeb manually very quickly. First, you need to get the Git source code, which GitWeb comes with, and generate the custom CGI script: @@ -56,7 +56,7 @@ Now, you need to make Apache use CGI for that script, for which you can add a Vi ServerName gitserver DocumentRoot /var/www/gitweb - Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch + Options +ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch AllowOverride All order allow,deny Allow from all diff --git a/book/04-git-server/sections/hosted.asc b/book/04-git-server/sections/hosted.asc index e9b8b06f2..6828f64e5 100644 --- a/book/04-git-server/sections/hosted.asc +++ b/book/04-git-server/sections/hosted.asc @@ -7,4 +7,4 @@ Even if you set up and run your own server internally, you may still want to use These days, you have a huge number of hosting options to choose from, each with different advantages and disadvantages. To see an up-to-date list, check out the GitHosting page on the main Git wiki at https://git.wiki.kernel.org/index.php/GitHosting[] -We'll cover using GitHub in detail in <<_github>>, as it is the largest Git host out there and you may need to interact with projects hosted on it in any case, but there are dozens more to choose from should you not want to set up your own Git server. +We'll cover using GitHub in detail in <>, as it is the largest Git host out there and you may need to interact with projects hosted on it in any case, but there are dozens more to choose from should you not want to set up your own Git server. diff --git a/book/04-git-server/sections/protocols.asc b/book/04-git-server/sections/protocols.asc index 1fa512c03..b30bf5017 100644 --- a/book/04-git-server/sections/protocols.asc +++ b/book/04-git-server/sections/protocols.asc @@ -1,98 +1,98 @@ -=== The Protocols +=== Die Protokolle -Git can use four major protocols to transfer data: Local, HTTP, Secure Shell (SSH) and Git. -Here we'll discuss what they are and in what basic circumstances you would want (or not want) to use them. +Git kann vier verschiedene Protokolle für die Datenübertragung verwenden: Lokal, HTTP, Secure Shell (SSH) und Git. +Hier werden wir klären, worum es sich handelt und unter welchen Rahmenbedingungen Sie sie verwenden könnten (oder nicht sollten). -==== Local Protocol +==== Lokales Protokoll (((protocols, local))) -The most basic is the _Local protocol_, in which the remote repository is in another directory on disk. -This is often used if everyone on your team has access to a shared filesystem such as an NFS mount, or in the less likely case that everyone logs in to the same computer. -The latter wouldn't be ideal, because all your code repository instances would reside on the same computer, making a catastrophic loss much more likely. +Das einfachste ist das _lokale Protokoll_, bei dem sich das entfernte Repository in einem anderen Verzeichnis auf demselben Host befindet. +Es wird häufig verwendet, wenn jeder in Ihrem Team Zugriff auf ein freigegebenes Dateisystem wie z.B. ein NFS-Mount hat, oder in dem selteneren Fall, dass sich jeder auf dem gleichen Computer anmeldet. +Letzteres wäre nicht ideal, da sich alle Ihre Code-Repository-Instanzen auf demselben Computer befinden würden, was einen katastrophalen Verlust viel wahrscheinlicher macht. -If you have a shared mounted filesystem, then you can clone, push to, and pull from a local file-based repository. -To clone a repository like this or to add one as a remote to an existing project, use the path to the repository as the URL. -For example, to clone a local repository, you can run something like this: +Wenn Sie ein gemeinsam genutztes gemountetes Dateisystem haben, können Sie ein lokales dateibasiertes Repository klonen, dort hin verschieben (engl. push to) und daraus ziehen (engl. pull). +Verwenden Sie den Pfad zum Repository als URL, um ein solches Repository zu klonen oder einem vorhandenen Projekt ein Remote-Repository hinzuzufügen. +Um beispielsweise ein lokales Repository zu klonen, können Sie Folgendes ausführen: [source,console] ---- $ git clone /srv/git/project.git ---- -Or you can do this: +oder auch das: [source,console] ---- $ git clone file:///srv/git/project.git ---- -Git operates slightly differently if you explicitly specify `file://` at the beginning of the URL. -If you just specify the path, Git tries to use hardlinks or directly copy the files it needs. -If you specify `file://`, Git fires up the processes that it normally uses to transfer data over a network which is generally a lot less efficient method of transferring the data. -The main reason to specify the `file://` prefix is if you want a clean copy of the repository with extraneous references or objects left out – generally after an import from another version-control system or something similar (see <<_git_internals>> for maintenance tasks). -We'll use the normal path here because doing so is almost always faster. +Git funktioniert etwas anders, wenn Sie `file://` explizit am Anfang der URL angeben. +Wenn Sie nur den Pfad angeben, versucht Git, Hardlinks zu verwenden oder die benötigten Dateien direkt zu kopieren. +Wenn Sie `file://` angeben, löst Git Prozesse aus, die normalerweise zum Übertragen von Daten über ein Netzwerk verwendet werden, was im Allgemeinen viel weniger effizient ist. +Der Hauptgrund für die Angabe des Präfix `file://` ist, wenn Sie eine saubere Kopie des Repositorys mit fremden Referenzen oder weggelassenen Objekten wünschen – in der Regel nach einem Import aus einem anderen VCS oder ähnlichem (siehe <> für Wartungsaufgaben. +Wir werden hier den normalen Pfad verwenden, denn das ist fast immer schneller. -To add a local repository to an existing Git project, you can run something like this: +Um ein lokales Repository zu einem bestehenden Git-Projekt hinzuzufügen, kann so vorgegangen werden: [source,console] ---- $ git remote add local_proj /srv/git/project.git ---- -Then, you can push to and pull from that remote as though you were doing so over a network. +Dann können Sie über Ihren neuen Remote-Namen `local_proj` auf dieses Remote-Repository pushen und von dort abrufen, als ob Sie dies über ein Netzwerk tun würden. -===== The Pros +===== Vorteile -The pros of file-based repositories are that they're simple and they use existing file permissions and network access. -If you already have a shared filesystem to which your whole team has access, setting up a repository is very easy. -You stick the bare repository copy somewhere everyone has shared access to and set the read/write permissions as you would for any other shared directory. -We'll discuss how to export a bare repository copy for this purpose in <<_git_on_the_server>>. +Die Vorteile dateibasierter Repositorys liegen darin, dass sie einfach sind und vorhandene Datei- und Netzwerk-Berechtigungen verwenden. +Wenn Sie bereits über ein freigegebenes Dateisystem verfügen, auf das Ihr gesamtes Team Zugriff hat, ist das Einrichten eines Repositorys sehr einfach. +Sie speichern die leere Repository-Kopie an einer Stelle, auf die jeder Zugriff hat, und legen die Lese- und Schreibberechtigungen wie bei jedem anderen freigegebenen Verzeichnis fest. +Informationen zum Exportieren einer Bare-Repository-Kopie für diesen Zweck finden Sie unter <>. -This is also a nice option for quickly grabbing work from someone else's working repository. -If you and a co-worker are working on the same project and they want you to check something out, running a command like `git pull /home/john/project` is often easier than them pushing to a remote server and you pulling down. +Das ist auch eine elegante Möglichkeit, um schnell Arbeiten aus dem Arbeits-Repository eines anderen zu holen. +Wenn Sie und ein Mitarbeiter am gleichen Projekt arbeiten und Sie etwas überprüfen möchten, ist es oft einfacher, einen Befehl wie `git pull /home/john/project` auszuführen, als auf einen Remote-Server zu pushen und anschließend von dort zu holen. -===== The Cons +===== Nachteile -The cons of this method are that shared access is generally more difficult to set up and reach from multiple locations than basic network access. -If you want to push from your laptop when you're at home, you have to mount the remote disk, which can be difficult and slow compared to network-based access. +Der Nachteil dieser Methode ist, dass der gemeinsame Zugriff in der Regel schwieriger einzurichten ist damit man von mehreren Standorten aus erreichbar ist als der einfache Netzwerkzugriff. +Wenn Sie von zu Hause mit Ihrem Laptop aus pushen möchten, müssen Sie das entfernte Verzeichnis einhängen (engl. mounten), was im Vergleich zum netzwerkbasierten Zugriff schwierig und langsamer sein kann. -It's important to mention that this isn't necessarily the fastest option if you're using a shared mount of some kind. -A local repository is fast only if you have fast access to the data. -A repository on NFS is often slower than the repository over SSH on the same server, allowing Git to run off local disks on each system. +Es ist wichtig zu erwähnen, dass es nicht unbedingt die schnellste Option ist, wenn Sie einen gemeinsamen Mount verwenden. +Ein lokales Repository ist nur dann schnell, wenn Sie schnellen Zugriff auf die Daten haben. +Ein Repository auf NFS-Mounts ist oft langsamer als der Zugriff auf das Repository über SSH auf demselben Server, während Git lokale Festplatten in jedem System nutzt. -Finally, this protocol does not protect the repository against accidental damage. -Every user has full shell access to the "remote" directory, and there is nothing preventing them from changing or removing internal Git files and corrupting the repository. +Schließlich schützt dieses Protokoll das Repository nicht vor unbeabsichtigten Schäden. + Jeder Benutzer hat vollen Shell-Zugriff auf das „remote“ Verzeichnis, und nichts hindert ihn daran, interne Git-Dateien zu ändern oder zu entfernen und das Repository zu beschädigen. -==== The HTTP Protocols +==== HTTP Protokolle -Git can communicate over HTTP in two different modes. -Prior to Git 1.6.6 there was only one way it could do this which was very simple and generally read-only. -In version 1.6.6 a new, smarter protocol was introduced that involved Git being able to intelligently negotiate data transfer in a manner similar to how it does over SSH. -In the last few years, this new HTTP protocol has become very popular since it's simpler for the user and smarter about how it communicates. -The newer version is often referred to as the ``Smart'' HTTP protocol and the older way as ``Dumb'' HTTP. -We'll cover the newer ``smart'' HTTP protocol first. +Git kann über HTTP in zwei verschiedenen Modi kommunizieren. +Vor Git 1.6.6 gab es nur einen einzigen Weg, der sehr einfach und im Allgemeinen „read-only“ war. +Mit der Version 1.6.6 wurde ein neues, intelligenteres Protokoll eingeführt, bei dem Git in der Lage ist, den Datentransfer intelligent auszuhandeln, ähnlich wie bei SSH. +In den letzten Jahren ist dieses neue HTTP-Protokoll sehr beliebt geworden, da es für den Benutzer einfacher und intelligenter in der Kommunikation ist. +Die neuere Version wird oft als _Smart_ HTTP Protokoll und die ältere als _Dumb_ HTTP bezeichnet. +Wir werden zuerst das neuere Smart HTTP-Protokoll besprechen. ===== Smart HTTP (((protocols, smart HTTP))) -The ``smart'' HTTP protocol operates very similarly to the SSH or Git protocols but runs over standard HTTP/S ports and can use various HTTP authentication mechanisms, meaning it's often easier on the user than something like SSH, since you can use things like username/password authentication rather than having to set up SSH keys. +Smart HTTP funktioniert sehr ähnlich wie die Protokolle SSH oder Git, läuft aber über Standard HTTPS-Ports und kann verschiedene HTTP-Authentifizierungsmechanismen verwenden, was bedeutet, dass es für den Benutzer oft einfacher ist als so etwas wie SSH, da Sie Eingaben wie Benutzername/Passwort-Authentifizierung verwenden können, anstatt SSH-Schlüssel einrichten zu müssen. -It has probably become the most popular way to use Git now, since it can be set up to both serve anonymously like the `git://` protocol, and can also be pushed over with authentication and encryption like the SSH protocol. -Instead of having to set up different URLs for these things, you can now use a single URL for both. -If you try to push and the repository requires authentication (which it normally should), the server can prompt for a username and password. -The same goes for read access. +Es ist wahrscheinlich der beliebteste Weg, heute Git zu verwenden, da es so eingerichtet werden kann, dass es sowohl anonym wie das Protokoll `git://` arbeitet, als auch mit Authentifizierung und Verschlüsselung wie das SSH-Protokoll betrieben werden kann. +Anstatt dafür verschiedene URLs einrichten zu müssen, können Sie nun eine einzige URL für beides verwenden. +Wenn Sie versuchen, einen Push durchzuführen und das Repository eine Authentifizierung erfordert (was normalerweise der Fall sein sollte), kann der Server nach einem Benutzernamen und einem Passwort fragen. +Gleiches gilt für den Lesezugriff. -In fact, for services like GitHub, the URL you use to view the repository online (for example, ``https://github.com/schacon/simplegit[]'') is the same URL you can use to clone and, if you have access, push over. +Für Dienste, wie GitHub, ist die URL, die Sie verwenden, um das Repository online anzuzeigen (z.B. https://github.com/schacon/simplegit[]), die gleiche URL, mit der Sie klonen und, wenn Sie Zugriff haben, verschieben können. ===== Dumb HTTP (((protocols, dumb HTTP))) -If the server does not respond with a Git HTTP smart service, the Git client will try to fall back to the simpler ``dumb'' HTTP protocol. -The Dumb protocol expects the bare Git repository to be served like normal files from the web server. -The beauty of the Dumb HTTP protocol is the simplicity of setting it up. -Basically, all you have to do is put a bare Git repository under your HTTP document root and set up a specific `post-update` hook, and you're done (See <<_git_hooks>>). -At that point, anyone who can access the web server under which you put the repository can also clone your repository. -To allow read access to your repository over HTTP, do something like this: +Wenn der Server nicht mit einem Git HTTP Smart Service antwortet, versucht der Git Client, auf das einfachere _Dumb_ HTTP Protokoll zurückzugreifen.. +Das Dumb-Protokoll erwartet von dem Bare-Git-Repository, dass es vom Webserver wie normale Dateien handelt wird. +Das Schöne an Dumb HTTP ist die Einfachheit der Einrichtung. +Im Grunde genommen müssen Sie nur ein leeres Git-Repository unter Ihre HTTP-Dokument-Root legen und einen bestimmten `post-update` Hook einrichten, und schon sind Sie fertig (siehe <>). +Ab diesem Zeitpunkt kann jeder, der auf den Webserver zugreifen kann, unter dem Sie das Repository ablegen, auch Ihr Repository klonen. +Um Lesezugriff auf Ihr Repository über HTTP zu ermöglichen, gehen Sie wie folgt vor: [source,console] ---- @@ -103,103 +103,103 @@ $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update ---- -That's all.(((hooks, post-update))) -The `post-update` hook that comes with Git by default runs the appropriate command (`git update-server-info`) to make HTTP fetching and cloning work properly. -This command is run when you push to this repository (over SSH perhaps); then, other people can clone via something like +Das war's.(((hooks, post-update))) +Der `post-update` Hook, der standardmäßig mit Git geliefert wird, führt den entsprechenden Befehl (`git update-server-info`) aus, um das HTTP-Abrufen und -Kloning ordnungsgemäß zu ermöglichen. +Dieser Befehl wird ausgeführt, wenn Sie in dieses Repository pushen (vielleicht über SSH); dann können andere Leute klonen über so etwas wie: [source,console] ---- $ git clone https://example.com/gitproject.git ---- -In this particular case, we're using the `/var/www/htdocs` path that is common for Apache setups, but you can use any static web server – just put the bare repository in its path. -The Git data is served as basic static files (see <<_git_internals>> for details about exactly how it's served). +In diesem speziellen Fall verwenden wir den Pfad `/var/www/htdocs`, der für Apache-Installationen üblich ist, Sie können aber jeden statischen Webserver verwenden – legen Sie einfach das leere Repository in seinen Pfad. +Die Git-Daten werden als einfache statische Dateien bereitgestellt (siehe Kapitel <> für Bedienungsdetails). -Generally you would either choose to run a read/write Smart HTTP server or simply have the files accessible as read-only in the Dumb manner. -It's rare to run a mix of the two services. +Im Allgemeinen würden Sie sich entweder einen Smart HTTP-Server zum Lesen und Schreiben betreiben oder die Dateien einfach als schreibgeschützt im Dumb-Modus zur Verfügung stellen. +Seltener wird ein Mix aus beiden Diensten angeboten. -===== The Pros +===== Vorteile -We'll concentrate on the pros of the Smart version of the HTTP protocol. +Wir werden uns auf die Vorteile der Smart Version des HTTP-Protokolls konzentrieren. -The simplicity of having a single URL for all types of access and having the server prompt only when authentication is needed makes things very easy for the end user. -Being able to authenticate with a username and password is also a big advantage over SSH, since users don't have to generate SSH keys locally and upload their public key to the server before being able to interact with it. -For less sophisticated users, or users on systems where SSH is less common, this is a major advantage in usability. -It is also a very fast and efficient protocol, similar to the SSH one. +Die Tatsache, dass eine einzige URL für alle Zugriffsarten und der Server-Prompt nur dann gebraucht wird, wenn eine Authentifizierung erforderlich ist, macht die Sache für den Endbenutzer sehr einfach. +Die Authentifizierung mit einem Benutzernamen und einem Passwort ist ebenfalls ein großer Vorteil gegenüber SSH, da Benutzer keine SSH-Schlüssel lokal generieren und ihren öffentlichen Schlüssel auf den Server hochladen müssen, bevor sie mit ihm interagieren können. +Für weniger anspruchsvolle Benutzer oder Benutzer auf Systemen, auf denen SSH weniger verbreitet ist, ist dies ein großer Vorteil in der Benutzerfreundlichkeit. +Es ist auch ein sehr schnelles und effizientes Protokoll, ähnlich dem SSH-Protokoll. -You can also serve your repositories read-only over HTTPS, which means you can encrypt the content transfer; or you can go so far as to make the clients use specific signed SSL certificates. +Sie können Ihre Repositorys auch schreibgeschützt über HTTPS bereitstellen, d.h. Sie können die Inhaltsübertragung verschlüsseln oder Sie können sogar so weit gehen, dass Clients bestimmte signierte SSL-Zertifikate verwenden müssen. -Another nice thing is that HTTP/S are such commonly used protocols that corporate firewalls are often set up to allow traffic through these ports. +Eine weitere schöne Sache ist, dass HTTPS ein so häufig verwendetes Protokoll ist, dass Unternehmens-Firewalls oft so eingerichtet sind, dass sie den Datenverkehr über diese Ports ermöglichen. -===== The Cons +===== Nachteile -Git over HTTP/S can be a little more tricky to set up compared to SSH on some servers. -Other than that, there is very little advantage that other protocols have over the ``Smart'' HTTP protocol for serving Git. +Git über HTTPS kann im Vergleich zu SSH auf einigen Servern etwas komplizierter einzurichten sein. +Abgesehen davon gibt es sehr wenig Vorteile, die andere Protokolle gegenüber Smart HTTP für die Bereitstellung von Git-Inhalten haben. -If you're using HTTP for authenticated pushing, providing your credentials is sometimes more complicated than using keys over SSH. -There are however several credential caching tools you can use, including Keychain access on OSX and Credential Manager on Windows, to make this pretty painless. -Read <<_credential_caching>> to see how to set up secure HTTP password caching on your system. +Wenn Sie HTTP für authentifiziertes Pushen verwenden, ist die Bereitstellung Ihrer Anmeldeinformationen manchmal komplizierter als die Verwendung von Schlüsseln über SSH. +Es gibt jedoch mehrere Tools zum Zwischenspeichern von Berechtigungen, die Sie verwenden könnten, darunter Keychain-Zugriff auf MacOS und Credential Manager unter Windows, um das ziemlich zu Vereinfachen. +Lesen Sie den Abschnitt <>, um zu erfahren, wie Sie ein sicheres HTTP-Passwort-Caching auf Ihrem System einrichten können. -==== The SSH Protocol +==== SSH Protocol (((protocols, SSH))) -A common transport protocol for Git when self-hosting is over SSH. -This is because SSH access to servers is already set up in most places – and if it isn't, it's easy to do. -SSH is also an authenticated network protocol; and because it's ubiquitous, it's generally easy to set up and use. +Ein gängiges Transportprotokoll für Git, wenn das Self-Hosting über SSH läuft. +Der SSH-Zugriff auf den Server ist in den meisten Fällen bereits eingerichtet – und wenn nicht, ist es einfach zu bewerkstelligen. +SSH ist auch ein authentifiziertes Netzwerkprotokoll, und da es allgegenwärtig ist, ist es im Allgemeinen einfach einzurichten und zu verwenden. -To clone a Git repository over SSH, you can specify ssh:// URL like this: +Um ein Git-Repository über SSH zu klonen, können Sie eine entsprechende `ssh://` URL angeben: [source,console] ---- -$ git clone ssh://user@server/project.git +$ git clone ssh://[user@]server/project.git ---- -Or you can use the shorter scp-like syntax for the SSH protocol: +Oder Sie können die kürzere scp-ähnliche Syntax für das SSH-Protokoll verwenden: [source,console] ---- -$ git clone user@server:project.git +$ git clone [user@]server:project.git ---- -You can also not specify a user, and Git assumes the user you're currently logged in as. +Wenn Sie in beiden Fällen oben keinen optionalen Benutzernamen angeben, benutzt Git den User, mit dem Sie aktuell angemeldet sind. -===== The Pros +===== Vorteile -The pros of using SSH are many. -First, SSH is relatively easy to set up – SSH daemons are commonplace, many network admins have experience with them, and many OS distributions are set up with them or have tools to manage them. -Next, access over SSH is secure – all data transfer is encrypted and authenticated. -Last, like the HTTP/S, Git and Local protocols, SSH is efficient, making the data as compact as possible before transferring it. +Die Vorteile bei der Verwendung von SSH sind vielfältig. +Erstens ist SSH relativ einfach einzurichten – SSH-Daemons sind weit verbreitet, viele Netzwerkadministratoren haben Erfahrung mit ihnen und viele Betriebssystem-Distributionen werden mit ihnen eingerichtet oder haben Werkzeuge, um sie zu verwalten. +Als nächstes ist der Zugriff über SSH sicher – der gesamte Datentransfer wird verschlüsselt und authentifiziert. +Schließlich ist SSH, wie die Protokolle HTTPS, Git und Local effizient und komprimiert die Daten vor der Übertragung so stark wie möglich. -===== The Cons +===== Nachteile -The negative aspect of SSH is that you can't serve anonymous access of your repository over it. -People must have access to your machine over SSH to access it, even in a read-only capacity, which doesn't make SSH access conducive to open source projects. -If you're using it only within your corporate network, SSH may be the only protocol you need to deal with. -If you want to allow anonymous read-only access to your projects and also want to use SSH, you’ll have to set up SSH for you to push over but something else for others to fetch over. +Die negative Seite von SSH ist, dass es keinen anonymen Zugriff auf Ihr Git-Repository unterstützt. +Wenn Sie SSH verwenden, _müssen_ Benutzer über einen SSH-Zugriff auf Ihren Computer verfügen, auch wenn sie nur über Lesezugriff verfügen. Das macht SSH in Open Source-Projekten ungeeignet, wenn, möglicherweise, die Benutzer Ihr Repository einfach nur klonen möchten, um es zu überprüfen. +Wenn Sie es nur in Ihrem Unternehmensnetzwerk verwenden, ist SSH möglicherweise das einzige Protokoll, mit dem Sie sich befassen müssen. +Wenn Sie anonymen schreibgeschützten Zugriff auf Ihre Projekte und die Verwendung von SSH zulassen möchten, müssen Sie SSH einrichten, damit Sie Push-Vorgänge ausführen können, aber noch zusätzliche Optionen damit andere Benutzer auch abrufen können. -==== The Git Protocol +==== Git Protokoll (((protocols, git))) -Next is the Git protocol. -This is a special daemon that comes packaged with Git; it listens on a dedicated port (9418) that provides a service similar to the SSH protocol, but with absolutely no authentication. -In order for a repository to be served over the Git protocol, you must create the `git-daemon-export-ok` file – the daemon won't serve a repository without that file in it – but other than that there is no security. -Either the Git repository is available for everyone to clone or it isn't. -This means that there is generally no pushing over this protocol. -You can enable push access; but given the lack of authentication, if you turn on push access, anyone on the internet who finds your project's URL could push to your project. -Suffice it to say that this is rare. - -===== The Pros - -The Git protocol is often the fastest network transfer protocol available. -If you’re serving a lot of traffic for a public project or serving a very large project that doesn't require user authentication for read access, it’s likely that you'll want to set up a Git daemon to serve your project. -It uses the same data-transfer mechanism as the SSH protocol but without the encryption and authentication overhead. - -===== The Cons - -The downside of the Git protocol is the lack of authentication. -It's generally undesirable for the Git protocol to be the only access to your project. -Generally, you'll pair it with SSH or HTTPS access for the few developers who have push (write) access and have everyone else use `git://` for read-only access. -It's also probably the most difficult protocol to set up. -It must run its own daemon, which requires `xinetd` configuration or the like, which isn't always a walk in the park. -It also requires firewall access to port 9418, which isn't a standard port that corporate firewalls always allow. -Behind big corporate firewalls, this obscure port is commonly blocked. +Und schließlich haben wir das Git-Protokoll. +Es ist ein spezieller Daemon, der mit Git ausgeliefert wird, der auf einem dedizierten Port (9418) lauscht und der einen Dienst bereitstellt, ähnlich dem des SSH-Protokolls, aber ohne jegliche Authentifizierung +Damit ein Repository über das Git-Protokoll bedient werden kann, müssen Sie eine `git-daemon-export-ok` Datei erstellen – der Daemon wird ohne diese Datei kein Repository bedienen, weil es sonst keine Sicherheit gibt. +Entweder ist das Git-Repository für jeden zugänglich, um zu klonen, oder für Keinen. +Das bedeutet, dass es in der Regel keinen Push über dieses Protokoll gibt. +Sie können den Push-Zugriff aktivieren, aber angesichts der fehlenden Authentifizierung kann jeder im Internet, der die URL Ihres Projekts findet, zu diesem Projekt pushen. +Es reicht aus, zu sagen, dass das selten vorkommt. + +===== Vorteile + +Das Git-Protokoll ist oft als erstes Netzwerkübertragungsprotokoll verfügbar. +Wenn Sie viel Traffic für ein öffentliches Projekt bereitstellen oder ein sehr großes Projekt, das keine Benutzerauthentifizierung für den Lesezugriff benötigt, dann wollen Sie voraussichtlich einen Git-Daemon einrichten, der Ihr Projekt unterstützt. +Er verwendet den gleichen Datenübertragungsmechanismus wie das SSH-Protokoll, jedoch ohne den Aufwand für Verschlüsselung und Authentifizierung. + +===== Nachteile + +Der Nachteil des Git-Protokolls ist die fehlende Authentifizierung. +Es ist generell nachteilig, wenn das Git-Protokoll der einzige Zugang zu Ihrem Projekt ist. +Im Allgemeinen werden Sie es mit einem SSH- oder HTTPS-Zugriff für die wenigen Entwickler koppeln, die Push (Schreib-)Zugriff haben und alle anderen `git://` für den Lesezugriff verwenden lassen. +Es ist wahrscheinlich auch das am schwierigsten einzurichtende Protokoll. +Es muss seinen eigenen Daemon laufen lassen, der eine `xinetd` oder `systemd` Konfiguration oder dergleichen erfordert, was nicht immer ein Park-Spaziergang ist. +Es erfordert auch einen Firewall-Zugang auf Port 9418, der kein Standardport ist, den Unternehmens-Firewalls immer zulassen. +Hinter großen Firmen-Firewalls wird dieser „obskure“ Port häufig blockiert. diff --git a/book/04-git-server/sections/setting-up-server.asc b/book/04-git-server/sections/setting-up-server.asc index 345b17bc5..17fd9dbdb 100644 --- a/book/04-git-server/sections/setting-up-server.asc +++ b/book/04-git-server/sections/setting-up-server.asc @@ -4,7 +4,13 @@ Let's walk through setting up SSH access on the server side. In this example, you'll use the `authorized_keys` method for authenticating your users. We also assume you're running a standard Linux distribution like Ubuntu. -First, you create a `git` user and a `.ssh` directory for that user. + +[NOTE] +==== +A good deal of what is described here can be automated by using the `ssh-copy-id` command, rather than manually copying and installing public keys. +==== + +First, you create a `git` user account and a `.ssh` directory for that user. [source,console] ---- @@ -80,25 +86,25 @@ $ git push origin master With this method, you can quickly get a read/write Git server up and running for a handful of developers. You should note that currently all these users can also log into the server and get a shell as the `git` user. -If you want to restrict that, you will have to change the shell to something else in the `passwd` file. +If you want to restrict that, you will have to change the shell to something else in the `/etc/passwd` file. -You can easily restrict the `git` user to only doing Git activities with a limited shell tool called `git-shell` that comes with Git. -If you set this as your `git` user's login shell, then the `git` user can't have normal shell access to your server. -To use this, specify `git-shell` instead of bash or csh for your user's login shell. -To do so, you must first add `git-shell` to `/etc/shells` if it's not already there: +You can easily restrict the `git` user account to only Git-related activities with a limited shell tool called `git-shell` that comes with Git. +If you set this as the `git` user account's login shell, then that account can't have normal shell access to your server. +To use this, specify `git-shell` instead of bash or csh for that account's login shell. +To do so, you must first add the full pathname of the `git-shell` command to `/etc/shells` if it's not already there: [source,console] ---- $ cat /etc/shells # see if `git-shell` is already in there. If not... $ which git-shell # make sure git-shell is installed on your system. -$ sudo vim /etc/shells # and add the path to git-shell from last command +$ sudo -e /etc/shells # and add the path to git-shell from last command ---- -Now you can edit the shell for a user using `chsh `: +Now you can edit the shell for a user using `chsh -s `: [source,console] ---- -$ sudo chsh git # and enter the path to git-shell, usually: /usr/bin/git-shell +$ sudo chsh git -s $(which git-shell) ---- Now, the `git` user can only use the SSH connection to push and pull Git repositories and can't shell onto the machine. diff --git a/book/04-git-server/sections/smart-http.asc b/book/04-git-server/sections/smart-http.asc index 967fd0e59..60bdd3097 100644 --- a/book/04-git-server/sections/smart-http.asc +++ b/book/04-git-server/sections/smart-http.asc @@ -4,7 +4,7 @@ We now have authenticated access through SSH and unauthenticated access through `git://`, but there is also a protocol that can do both at the same time. Setting up Smart HTTP is basically just enabling a CGI script that is provided with Git called `git-http-backend` on the server.(((git commands, "http-backend"))) This CGI will read the path and headers sent by a `git fetch` or `git push` to an HTTP URL and determine if the client can communicate over HTTP (which is true for any client since version 1.6.6). -If the CGI sees that the client is smart, it will communicate smartly with it, otherwise it will fall back to the dumb behavior (so it is backward compatible for reads with older clients). +If the CGI sees that the client is smart, it will communicate smartly with it; otherwise it will fall back to the dumb behavior (so it is backward compatible for reads with older clients). Let's walk through a very basic setup. We'll set this up with Apache as the CGI server. @@ -13,12 +13,12 @@ If you don't have Apache setup, you can do so on a Linux box with something like [source,console] ---- $ sudo apt-get install apache2 apache2-utils -$ a2enmod cgi alias env rewrite +$ a2enmod cgi alias env ---- -This also enables the `mod_cgi`, `mod_alias`, `mod_env`, and `mod_rewrite` modules, which are all needed for this to work properly. +This also enables the `mod_cgi`, `mod_alias`, and `mod_env` modules, which are all needed for this to work properly. -You’ll also need to set the Unix user group of the `/srv/git` directories to `www-data` so your web server can read- and write-access the repositories, because the Apache instance running the CGI script will (by default) be running as that user: +You'll also need to set the Unix user group of the `/srv/git` directories to `www-data` so your web server can read- and write-access the repositories, because the Apache instance running the CGI script will (by default) be running as that user: [source,console] ---- @@ -40,19 +40,12 @@ Finally you'll want to tell Apache to allow requests to `git-http-backend` and m [source,console] ---- -RewriteEngine On -RewriteCond %{QUERY_STRING} service=git-receive-pack [OR] -RewriteCond %{REQUEST_URI} /git-receive-pack$ -RewriteRule ^/git/ - [E=AUTHREQUIRED] - AuthType Basic AuthName "Git Access" AuthUserFile /srv/git/.htpasswd + Require expr !(%{QUERY_STRING} -strmatch '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#) Require valid-user - Order deny,allow - Deny from env=AUTHREQUIRED - Satisfy any ---- @@ -75,5 +68,5 @@ You can do this with nearly any CGI-capable web server, so go with the one that [NOTE] ==== -For more information on configuring authentication in Apache, check out the Apache docs here: http://httpd.apache.org/docs/current/howto/auth.html[] +For more information on configuring authentication in Apache, check out the Apache docs here: https://httpd.apache.org/docs/current/howto/auth.html[] ==== diff --git a/book/05-distributed-git/1-distributed-git.asc b/book/05-distributed-git/1-distributed-git.asc deleted file mode 100644 index e9aee1a02..000000000 --- a/book/05-distributed-git/1-distributed-git.asc +++ /dev/null @@ -1,20 +0,0 @@ -[[_distributed_git]] -== Verteiltes Arbeiten mit Git - -(((distributed git))) -Jetzt, wo Sie ein entferntes Repository als Ort eingerichtet haben, wo alle Entwickler ihren Code miteinander teilen können, und Sie mit den grundlegenden Git-Anweisungen innerhalb eines lokalen Arbeitsablaufs vertraut sind, werden wir uns anschauen, wie Sie einige der verteilten Arbeitsabläufe anwenden können, die Git Ihnen ermöglicht. - -In diesem Kapitel werden Sie sehen, wie Sie mit Git in einer verteilten Umgebung als Mitarbeiter und als Integrator arbeiten. -Das bedeutet, Sie werden erfahren, wie Sie Quelltext erfolgreich zu einem Projekt besteuern und wie Sie es sich und dem Projektbetreiber dabei so leicht wie möglich machen, und wie Sie selbst erfolgreich ein Projekt pflegen, an dem mehrere Entwickler beteiligt sind. - -include::sections/distributed-workflows.asc[] - -include::sections/contributing.asc[] - -include::sections/maintaining.asc[] - -=== Zusammenfassung - -Sie sollten einigermaßen vertraut damit sein, an einem Projekt in Git mitzuarbeiten, Ihre eigenen Projekte zu pflegen oder die Beiträge anderer Entwickler zu integrieren. -Glückwunsch, jetzt sind Sie ein erfolgreicher Git-Entwickler. -Im nächsten Kapitel werden Sie erfahren, wie Sie den größten und bekanntesten Git-Hosting-Dienst, GitHub, benutzen können. diff --git a/book/05-distributed-git/images/benevolent-dictator.png b/book/05-distributed-git/images/benevolent-dictator.png deleted file mode 100644 index aeb47e7cf..000000000 Binary files a/book/05-distributed-git/images/benevolent-dictator.png and /dev/null differ diff --git a/book/05-distributed-git/images/integration-manager.png b/book/05-distributed-git/images/integration-manager.png deleted file mode 100644 index fd0d531eb..000000000 Binary files a/book/05-distributed-git/images/integration-manager.png and /dev/null differ diff --git a/book/05-distributed-git/images/large-merges-1.png b/book/05-distributed-git/images/large-merges-1.png deleted file mode 100644 index d3ee025ae..000000000 Binary files a/book/05-distributed-git/images/large-merges-1.png and /dev/null differ diff --git a/book/05-distributed-git/images/large-merges-2.png b/book/05-distributed-git/images/large-merges-2.png deleted file mode 100644 index 2d23e691b..000000000 Binary files a/book/05-distributed-git/images/large-merges-2.png and /dev/null differ diff --git a/book/05-distributed-git/images/managed-team-1.png b/book/05-distributed-git/images/managed-team-1.png deleted file mode 100644 index 489b6322e..000000000 Binary files a/book/05-distributed-git/images/managed-team-1.png and /dev/null differ diff --git a/book/05-distributed-git/images/managed-team-2.png b/book/05-distributed-git/images/managed-team-2.png deleted file mode 100644 index 25c2db2b6..000000000 Binary files a/book/05-distributed-git/images/managed-team-2.png and /dev/null differ diff --git a/book/05-distributed-git/images/managed-team-3.png b/book/05-distributed-git/images/managed-team-3.png deleted file mode 100644 index a8a08a707..000000000 Binary files a/book/05-distributed-git/images/managed-team-3.png and /dev/null differ diff --git a/book/05-distributed-git/images/managed-team-flow.png b/book/05-distributed-git/images/managed-team-flow.png deleted file mode 100644 index 18be331de..000000000 Binary files a/book/05-distributed-git/images/managed-team-flow.png and /dev/null differ diff --git a/book/05-distributed-git/images/merging-workflows-1.png b/book/05-distributed-git/images/merging-workflows-1.png deleted file mode 100644 index 461de6e22..000000000 Binary files a/book/05-distributed-git/images/merging-workflows-1.png and /dev/null differ diff --git a/book/05-distributed-git/images/merging-workflows-2.png b/book/05-distributed-git/images/merging-workflows-2.png deleted file mode 100644 index 5a0d1fcf8..000000000 Binary files a/book/05-distributed-git/images/merging-workflows-2.png and /dev/null differ diff --git a/book/05-distributed-git/images/merging-workflows-3.png b/book/05-distributed-git/images/merging-workflows-3.png deleted file mode 100644 index f3a32367c..000000000 Binary files a/book/05-distributed-git/images/merging-workflows-3.png and /dev/null differ diff --git a/book/05-distributed-git/images/merging-workflows-4 2.png b/book/05-distributed-git/images/merging-workflows-4 2.png deleted file mode 100644 index 32ae908e1..000000000 Binary files a/book/05-distributed-git/images/merging-workflows-4 2.png and /dev/null differ diff --git a/book/05-distributed-git/images/merging-workflows-4.png b/book/05-distributed-git/images/merging-workflows-4.png deleted file mode 100644 index 2ad04c13f..000000000 Binary files a/book/05-distributed-git/images/merging-workflows-4.png and /dev/null differ diff --git a/book/05-distributed-git/images/merging-workflows-5.png b/book/05-distributed-git/images/merging-workflows-5.png deleted file mode 100644 index 151cbd278..000000000 Binary files a/book/05-distributed-git/images/merging-workflows-5.png and /dev/null differ diff --git a/book/05-distributed-git/images/public-small-1.png b/book/05-distributed-git/images/public-small-1.png deleted file mode 100644 index efcb90d6b..000000000 Binary files a/book/05-distributed-git/images/public-small-1.png and /dev/null differ diff --git a/book/05-distributed-git/images/public-small-2.png b/book/05-distributed-git/images/public-small-2.png deleted file mode 100644 index 9dd40631b..000000000 Binary files a/book/05-distributed-git/images/public-small-2.png and /dev/null differ diff --git a/book/05-distributed-git/images/public-small-3.png b/book/05-distributed-git/images/public-small-3.png deleted file mode 100644 index fa06f77e4..000000000 Binary files a/book/05-distributed-git/images/public-small-3.png and /dev/null differ diff --git a/book/05-distributed-git/images/rebasing-1.png b/book/05-distributed-git/images/rebasing-1.png deleted file mode 100644 index cd3efa163..000000000 Binary files a/book/05-distributed-git/images/rebasing-1.png and /dev/null differ diff --git a/book/05-distributed-git/images/rebasing-2.png b/book/05-distributed-git/images/rebasing-2.png deleted file mode 100644 index 55ca410be..000000000 Binary files a/book/05-distributed-git/images/rebasing-2.png and /dev/null differ diff --git a/book/05-distributed-git/images/small-team-1.png b/book/05-distributed-git/images/small-team-1.png deleted file mode 100644 index d13654ec5..000000000 Binary files a/book/05-distributed-git/images/small-team-1.png and /dev/null differ diff --git a/book/05-distributed-git/images/small-team-2.png b/book/05-distributed-git/images/small-team-2.png deleted file mode 100644 index 1af627874..000000000 Binary files a/book/05-distributed-git/images/small-team-2.png and /dev/null differ diff --git a/book/05-distributed-git/images/small-team-3.png b/book/05-distributed-git/images/small-team-3.png deleted file mode 100644 index 3b01de8ba..000000000 Binary files a/book/05-distributed-git/images/small-team-3.png and /dev/null differ diff --git a/book/05-distributed-git/images/small-team-4.png b/book/05-distributed-git/images/small-team-4.png deleted file mode 100644 index b5e8c00b2..000000000 Binary files a/book/05-distributed-git/images/small-team-4.png and /dev/null differ diff --git a/book/05-distributed-git/images/small-team-5.png b/book/05-distributed-git/images/small-team-5.png deleted file mode 100644 index e0215e4fb..000000000 Binary files a/book/05-distributed-git/images/small-team-5.png and /dev/null differ diff --git a/book/05-distributed-git/images/small-team-6.png b/book/05-distributed-git/images/small-team-6.png deleted file mode 100644 index 357944415..000000000 Binary files a/book/05-distributed-git/images/small-team-6.png and /dev/null differ diff --git a/book/05-distributed-git/images/small-team-7.png b/book/05-distributed-git/images/small-team-7.png deleted file mode 100644 index 6bbbc2d8b..000000000 Binary files a/book/05-distributed-git/images/small-team-7.png and /dev/null differ diff --git a/book/05-distributed-git/images/small-team-flow.png b/book/05-distributed-git/images/small-team-flow.png deleted file mode 100644 index c8589ba6b..000000000 Binary files a/book/05-distributed-git/images/small-team-flow.png and /dev/null differ diff --git a/book/05-distributed-git/sections/contributing.asc b/book/05-distributed-git/sections/contributing.asc index 8995f7341..506c4c35a 100644 --- a/book/05-distributed-git/sections/contributing.asc +++ b/book/05-distributed-git/sections/contributing.asc @@ -2,7 +2,6 @@ === An einem Projekt mitarbeiten (((contributing))) -<<<<<<< HEAD Die größte Schwierigkeit bei der Beschreibung der Mitarbeit an einem Projekt besteht darin, dass es eine große Anzahl von Variationen gibt, wie dies geschehen kann. Da Git sehr flexibel ist, bietet es den Menschen viele Möglichkeiten der Zusammenarbeit, und es ist problematisch zu beschreiben, wie Sie mitarbeiten sollten, da jedes Projekt ein bisschen anders ist. Einige der variablen Größen dabei sind die Anzahl der aktiven Mitarbeiter, der gewählte Arbeitsablauf, Ihre Zugriffsrechte und möglicherweise eine externe Methode der Mitarbeit. @@ -30,35 +29,6 @@ Und wie häufig tun Sie das? All diese Aspekte haben Einfluss darauf, wie Sie effektiv an einem Projekt mitarbeiten können und welche Arbeitsabläufe bevorzugt werden oder verfügbar für Sie sind. Wir werden verschiedene Aspekte davon in einer Reihe von Fallbeispielen betrachten, wobei wir mit simplen Beispielen anfangen und später komplexere Szenarios besprechen. Sie sollten in der Lage sein, anhand dieser Beispiele die spezifischen Arbeitsabläufe zu erstellen, die Sie in der Praxis benötigen. -======= -The main difficulty with describing how to contribute to a project is that there are a huge number of variations on how it's done. -Because Git is very flexible, people can and do work together in many ways, and it's problematic to describe how you should contribute – every project is a bit different. -Some of the variables involved are active contributor count, chosen workflow, your commit access, and possibly the external contribution method. - -The first variable is active contributor count – how many users are actively contributing code to this project, and how often? -In many instances, you'll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. -For larger companies or projects, the number of developers could be in the thousands, with hundreds or thousands of commits coming in each day. -This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. -Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. -How can you keep your code consistently up to date and your commits valid? - -The next variable is the workflow in use for the project. -Is it centralized, with each developer having equal write access to the main codeline? -Does the project have a maintainer or integration manager who checks all the patches? -Are all the patches peer-reviewed and approved? -Are you involved in that process? -Is a lieutenant system in place, and do you have to submit your work to them first? - -The next variable is your commit access. -The workflow required in order to contribute to a project is much different if you have write access to the project than if you don't. -If you don't have write access, how does the project prefer to accept contributed work? -Does it even have a policy? -How much work are you contributing at a time? -How often do you contribute? - -All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. -We'll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 [[_commit_guidelines]] ==== Richtlinien für Commits @@ -68,9 +38,8 @@ Ein gute Richtlinie für das Erzeugen von Commits zu haben und sich daran zu hal Das Git-Projekt stellt ein Dokument bereit, welches eine Reihe von guten Tipps für das Erzeugen von Commits zum Übermitteln von Patches beinhaltet. Sie können die Tipps in der Datei `Documentation/SubmittingPatches` im Git-Quellcode nachlesen. (((git commands, diff, check))) -<<<<<<< HEAD Als Erstes wollen Sie keinerlei Leerzeichenfehler übermitteln. -Git bietet eine einfache Möglichkeit, dies zu überprüfen - bevor Sie einen Commit vornehmen, führen Sie die Anweisung `git diff --check` aus, welche mögliche Leerzeichenfehler erkennt und für Sie auflistet. +Git bietet eine einfache Möglichkeit, dies zu überprüfen - bevor Sie einen Commit vornehmen, führen Sie die Anweisung `git diff --check` aus, welche mögliche Leerzeichenfehler erkennt und für Sie auflistet. .Ausgabe von `git diff --check`. image::images/git-diff-check.png[Ausgabe von `git diff --check`.] @@ -82,6 +51,7 @@ Wenn Sie können, versuchen Sie, Ihre Änderungen leicht verdaulich zu machen - Auch wenn Sie am Wochenende keine Commits durchführen, nutzen Sie am Montag die Staging Area, um Ihre Änderungen aufzuteilen in wenigstens einen Commit für jeden Teilaspekt mit jeweils einer sinnvollen Nachricht. Wenn einige der Änderungen die selbe Datei modifizieren, benutzen Sie die Anweisung `git add --patch`, um Dateien partiell zur Staging Area hinzuzufügen (detailiert dargestellt im Abschnitt <<_interactive_staging>>). Der Schnappschuss vom Projekt an der Spitze des Branches ist der Selbe, ob Sie einen oder fünf Commits durchgeführt haben, solange nur all die Änderungen irgendwann hinzugefügt werden. Versuchen Sie also, die Dinge zu vereinfachen für Ihre Entwicklerkollegen, die Ihre Änderungen begutachten müssen. + Dieser Ansatz macht es außerdem einfacher, einen Satz von Änderungen zu entfernen oder rückgängig zu machen, falls das später nötig wäre. <<_rewriting_history>> beschreibt eine Reihe nützlicher Git-Tricks zum Umschreiben des Verlaufs oder um interaktiv Dateien zur Staging Area hinzuzufügen. Verwenden Sie diese Werkzeuge, um einen sauberen und leicht verständlichen Verlauf aufzubauen, bevor Sie Ihre Arbeit jemand anderem schicken. @@ -89,94 +59,58 @@ Ein weitere Sache, die Sie nicht vergessen sollten, ist die Commit-Nachricht. Wenn man sich angewöhnt, aussagekräftige und hochwertige Commit-Nachrichten zu schreiben, ist die Benutzung von Git viel einfacher und es erleichtert die Zusammenarbeit. In der Regel sollte Ihre Commit-Nachricht mit einer einzelnen Zeile anfangen, die nicht länger als 50 Zeichen sein sollte und die Änderungen kurz und bündig beschreibt, gefolgt von einer leeren Zeile, welcher eine ausführlichere Beschreibung der Änderungen folgt. Das Git-Projekt fordert, dass die detailliertere Erklärung Ihre Motivation für die Änderungen beinhaltet und deren Implementierung dem vorhergehenden Verhalten gegenüberstellt. Das ist eine gute Richtlinie, an die man sich halten sollte. -Es empfiehlt sich außerdem, die Gegenwartsform des Imperativ in diesen Nachrichten zu benutzen. -Mit anderen Worten, nutzen Sie Anweisungen. -Anstatt ``Ich habe Test hinzugefügt für'' oder ``Tests hinzufügend für'' benutzen Sie ``Füge Tests hinzu für''. -Hier ist ein Muster, welches ursprünglich von Tim Pope stammt: - -[source,text] ------ -Kurze (50 Zeichen oder weniger) Zusammenfassung der Änderungen -======= -First, you don't want to submit any whitespace errors. -Git provides an easy way to check for this – before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. - -.Output of `git diff --check`. -image::images/git-diff-check.png[Output of `git diff --check`.] - -If you run that command before committing, you can tell if you're about to commit whitespace issues that may annoy other developers. - -Next, try to make each commit a logically separate changeset. -If you can, try to make your changes digestible – don't code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. -Even if you don't commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. -If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in <<_interactive_staging>>). -The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. -This approach also makes it easier to pull out or revert one of the changesets if you need to later. -<<_rewriting_history>> describes a number of useful Git tricks for rewriting history and interactively staging files – use these tools to help craft a clean and understandable history before sending the work to someone else. - -The last thing to keep in mind is the commit message. -Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. -As a general rule, your messages should start with a single line that's no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. -The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior – this is a good guideline to follow. -It's also a good idea to use the imperative present tense in these messages. -In other words, use commands. -Instead of ``I added tests for'' or ``Adding tests for,'' use ``Add tests for.'' -Here is a http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[template originally written by Tim Pope]: +Es empfiehlt sich außerdem, die Gegenwartsform des Imperativ in diesen Nachrichten zu benutzen. Mit anderen Worten, verwenden Sie Anweisungen. Anstatt „Ich habe Test hinzugefügt für“ oder „Tests hinzufügend für“ benutzen Sie „Füge Tests hinzu für“. +Hier ist ein https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[Muster, welches ursprünglich von Tim Pope stammt]: [source,text] ---- -Short (50 chars or less) summary of changes ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Kurze (50 Zeichen oder weniger) Zusammenfassung der Änderungen -Detailliert erklärender Text, wenn nötig. Beschränken Sie -diesen auf ca. 72 Zeichen. In Abhängigkeit vom Kontext wird -die erste Zeile manchmal wie die Betreff-Zeile einer E-Mail -behandelt und der übrige Text wie der Textkörper der -Nachricht. Die leere Zeile, welche die Zusammenfassung vom -Text trennt, ist kritisch (außer Sie lassen den Text komplett -weg); Werkzeuge wie Rebase können durcheinander kommen, wenn +Detailliert erklärender Text, wenn nötig. Beschränken Sie diesen auf +ca. 72 Zeichen. In Abhängigkeit vom Kontext wird die erste Zeile +manchmal wie die Betreff-Zeile einer E-Mail behandelt und der übrige +Text wie der Textkörper der Nachricht. Die leere Zeile, welche die +Zusammenfassung vom Text trennt, ist kritisch (außer Sie lassen den Text +komplett weg); Werkzeuge wie Rebase können durcheinander kommen, wenn Sie beide gleichzeitig verwenden. Weitere Absätze folgen jeweils nach leeren Zeilen. - - Aufzählungspunkte kann man auch verwenden +. Aufzählungspunkte kann man auch verwenden + +* Typischer Weise nutzt man Bindestriche oder Sternchen + als Aufzählungszeichen, denen ein einzelnes Leerzeichen + vorangestellt wird, die einzelnen Punkte werden durch + leere Zeilen getrennt, die Konventionen variieren hier -<<<<<<< HEAD - - Typischer Weise nutzt man Bindestriche oder Sternchen - als Aufzählungszeichen, denen ein einzelnes Leerzeichen - vorangestellt wird, die einzelnen Punkte werden durch - leere Zeilen getrennt, die Konventionen variieren hier - ------ -======= - - Typically a hyphen or asterisk is used for the bullet, - preceded by a single space, with blank lines in - between, but conventions vary here + einen hängenden Einzug benutzen ---- ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 Wenn alle Ihre Commit-Nachrichten so aussehen, werden die Dinge für Sie und die Entwickler, mit denen Sie zusammenarbeiten, viel einfacher sein. -Das Git-Projekt selbst hat wohl-formatierte Commit-Nachrichten - führen Sie mal die Anweisung `git log --no-merges` aus, um zu sehen, wie ein angenehm formatierter Commit-Verlauf eines Projektes aussieht. +Das Git-Projekt selbst hat wohl-formatierte Commit-Nachrichten – führen Sie mal die Anweisung `git log --no-merges` aus, um zu sehen, wie ein angenehm formatierter Commit-Verlauf eines Projektes aussieht. In den folgenden Beispielen und fast überall in diesem Buch finden Sie der Kürze halber keine angenehm formatierten Meldungen wie diese. Stattdessen wird die Anweisung `git commit` zusammen mit der Option `-m` verwendet. Also folgen Sie meinen Worten und nicht meinem Beispiel. -<<<<<<< HEAD -======= -For the sake of brevity, the following examples, and most examples in other parts of this book, don't have nicely-formatted messages like this; instead, we use the `-m` option to `git commit`. -Do as we say, not as we do. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 + +[NOTE] +.Mach es wie wir sagen, nicht wie wir es tun. +==== +Der Kürze halber haben viele der Beispiele in diesem Buch keine gut formatierten Commit-Nachrichten wie diese. Stattdessen verwenden wir einfach die Option `-m`, um `-m` auszuführen. + +Kurz, mach es wie wir sagen, nicht wie wir es tun. +==== [[_private_team]] -==== Vertrauliches kleines Team +==== Privates kleines Team (((contributing, private small team))) Das einfachste Szenario, dem Sie sehr wahrscheinlich begegnen werden, ist ein vertrauliches Projekt mit einem oder zwei Entwicklern. -``Private'' in diesem Zusammenhang bedeutet "closed source" - nicht öffentlich zugänglich für die Außenwelt. +„Private“ in diesem Zusammenhang bedeutet „closed source“ - nicht öffentlich zugänglich für die Außenwelt. Sie und die anderen Entwickler haben alle Schreibzugriff auf das Repository. Sie können sich in diesem Umfeld an einen Arbeitsablauf halten, den Sie genauso auch bei Subversion oder einem anderen zentralisierten System verwenden könnten. -Sie genießen dann immer noch die Vorteile von Dingen, wie Commits offline durchführen zu können und erheblich einfacher Branches anzulegen und zusammenzuführen, aber der Arbeitsablauf kann sehr ähnlich sein. Der Hauptunterschied ist, dass das Zusammenführen eher auf der Client-Seite stattfindet als auf dem Server beim Durchführen eines Commits. +Sie genießen dann immer noch die Vorteile von Dingen, wie Commits offline durchführen zu können und erheblich einfacher Branches anzulegen und zusammenzuführen, der Arbeitsablauf kann sehr ähnlich sein. Der Hauptunterschied ist, dass das Zusammenführen eher auf der Client-Seite stattfindet als auf dem Server beim Durchführen eines Commits. Lassen Sie uns betrachten, wie es aussehen könnte, wenn zwei Entwickler damit beginnen, an einem gemeinsamen Repository zu arbeiten. Der erste Entwickler, John, klont das Repository, nimmt eine Änderung vor und führt lokal einen Commit durch. (Die Protokoll-Nachrichten wurden in diesen Beispielen durch `...` ersetzt, um das Ganze etwas zu kürzen.) @@ -194,7 +128,7 @@ $ git commit -am 'remove invalid default value' 1 files changed, 1 insertions(+), 1 deletions(-) ---- -Die zweite Entwicklerin, Jessica, tut das Selbe. Sie klont das Repository, ändert etwas und führt einen Commit durch. +Die zweite Entwicklerin, Jessica, tut dasselbe. Sie klont das Repository, ändert etwas und führt einen Commit durch. [source,console] ---- @@ -220,7 +154,12 @@ To jessica@githost:simplegit.git 1edee6b..fbff5bc master -> master ---- -John versucht ebenfalls, seine Änderungen hochzuladen: +Die letzte Zeile der obigen Ausgabe zeigt eine nützliche Rückmeldung aus aus der Push-Operation. +Das Ausgangsformat ist `.. fromref -> toref`, wobei `oldref` die alte Referenz bedeutet, `newref` die neue Referenz bedeutet, `fromref` der Name der zu verschiebenden lokalen Referenz ist und `toref` der Name der zu aktualisierenden Fernreferenz ist. +Sie werden ähnliche Ausgaben wie diese unten in den Diskussionsrunden sehen, so dass eine grundlegende Vorstellung der Bedeutung hilft, die verschiedenen Zustände der Repositorien zu verstehen. +Weitere Details finden Sie in der Dokumentation zu https://git-scm.com/docs/git-push[git-push]. + +In Fortsetzung dieses Beispiels nimmt John kurz darauf einige Änderungen vor, überträgt sie in sein lokales Repository und versucht, sie auf den gleichen Server zu verschieben: [source,console] ---- @@ -231,10 +170,12 @@ To john@githost:simplegit.git error: failed to push some refs to 'john@githost:simplegit.git' ---- -John ist es nicht gestattet, seine Änderungen hochzuladen, weil Jessica inzwischen ihre hochgeladen hat. +John ist es nicht gestattet, seine Änderungen hochzuladen, weil Jessica vorher _ihre_ hochgeladen hat. Dies zu verstehen, ist besonders wichtig, wenn Sie dem Umgang mit Subversion gewöhnt sind, weil Sie bemerkt haben werden, dass die beiden Entwickler nicht die gleiche Datei bearbeitet haben. -Obwohl Subversion automatisch das Zusammenführen auf dem Server durchführt, wenn zwei verschiedene Dateien bearbeitet werden, müssen Sie die Commits bei Git lokal zusammenführen. -John muss erst Jessicas Änderungen abholen und lokal mit seinen zusammenführen, bevor ihm das Hochladen gestattet wird. +Obwohl Subversion automatisch das Zusammenführen auf dem Server durchführt, wenn zwei verschiedene Dateien bearbeitet werden, müssen Sie die Commits bei Git _zuerst_ lokal zusammenführen. +Anders ausgedrückt: John muss erst Jessicas Änderungen abholen und lokal mit seinen zusammenführen, bevor ihm das Hochladen gestattet wird. + +Als ersten Schritt ruft John Jessicas Arbeit ab (dies ruft nur Jessicas Vorgängerarbeit ab, er verbindet sie noch nicht mit Johns Arbeit): [source,console] ---- @@ -249,7 +190,7 @@ Zu diesem Zeitpunkt sieht Johns lokales Repository ungefähr so aus: .Johns abzweigender Verlauf. image::images/small-team-1.png[John's divergent history.] -John hat einen Bezug zu den Änderungen, welche Jessica hochgeladen hat, aber er muss diese erst mit seiner eigenen Arbeit zusammenführen, bevor es ihm gestattet ist, selbst hochzuladen. +Jetzt kann John Jessicas Arbeit, die er abgerufen hat, mit seiner eigenen lokalen Arbeit zusammenführen: [source,console] ---- @@ -279,14 +220,13 @@ Schließlich sieht Johns Commit-Verlauf so aus: .Johns Verlauf nach dem Hochladen auf den `origin`-Server. image::images/small-team-3.png[John's history after pushing to the `origin` server.] -Jesicca hat in der Zwischenzeit an einem Themenbranch gearbeitet. -Sie hat einen Themenbranch namens `issue54` erzeugt und auf diesem Branch drei Commits durchgeführt. +Jesicca hat in der Zwischenzeit an einem neuen Branch gearbeitet. Sie hat einen Branch namens `issue54` erzeugt und auf diesem Branch drei Commits durchgeführt. Noch hat sie Johns Änderungen nicht vom Server abgeholt, sodass ihr Commit-Verlauf jetzt so aussieht: -.Jessicas Themenbranch. +.Jessicas Branches. image::images/small-team-4.png[Jessica's topic branch.] -Jessica möchte ihren Stand mit Johns synchronisieren, also führt sie die Anweisung `git fetch origin` aus: +Plötzlich erfährt Jessica, dass John neue Arbeit auf den Server geschoben hat und sie will sich das ansehen. Deshalb muss sie alle neuen Inhalte vom Server abrufen über die sie noch nicht verfügt: [source,console] ---- @@ -303,8 +243,8 @@ Jessicas Verlauf sieht nun so aus: .Jessicas Verlauf nach dem Abholen von Johns Änderungen. image::images/small-team-5.png[Jessica's history after fetching John's changes.] -Jessica denkt, dass ihr Themenbranch fertig ist, aber sie möchte wissen, welche Änderung sie mit ihrer Arbeit zusammenführen muss, damit sie ihrerseits hochladen kann. -Sie führt die Anweisung `git log` aus, um dies herauszufinden: +Jessica denkt, dass ihr Branch fertig ist, aber sie möchte wissen, welchen Teil von Johns abgerufenen Arbeiten sie in ihre Arbeit einbinden muss, damit sie ihrerseits hochladen kann. +Sie führt die Anweisung `git log` aus, um es herauszufinden: [source,console] ---- @@ -316,19 +256,14 @@ Date: Fri May 29 16:01:27 2009 -0700 remove invalid default value ---- -<<<<<<< HEAD -Bei der Syntax `issue54..origin/master` handelt es sich um einen log-Filter, der Git anweist, nur die Commits aufzulisten, welche auf dem letzteren Branch durchgeführt wurden (in diesem Fall `origin/master`) und die sich nicht auf dem ersten Branch befinden (in diesem Fall `issue54`). Wir werden uns diese Syntax detailliert in <<_commit_ranges>>. +Bei der Syntax `issue54..origin/master` handelt es sich um einen log-Filter, der Git anweist, nur die Commits aufzulisten, welche auf dem letzteren Branch durchgeführt wurden (in diesem Fall `origin/master`) und die sich nicht auf dem ersten Branch befinden (in diesem Fall `issue54`). +Wir werden diese Syntax detailliert in <> erläutern. -Fürs Erste können wir an der Ausgabe erkennen, dass es einen einzelnen Commit von John gibt, den Jessica noch nicht bei sich eingefügt hat. Dieser einzelne Commit modifiziert ihre lokalen Änderungen, wenn sie ihren Branch mit `origin/master` zusammenführt. -======= -The `issue54..origin/master` syntax is a log filter that asks Git to only show the list of commits that are on the latter branch (in this case `origin/master`) that are not on the first branch (in this case `issue54`). -We'll go over this syntax in detail in <<_commit_ranges>>. +Fürs Erste können wir an der Ausgabe erkennen, dass es einen einzelnen Commit von John gibt, den Jessica noch nicht bei sich eingefügt hat. +Dieser einzelne Commit modifiziert ihre lokalen Änderungen, wenn sie ihren Branch mit `origin/master` zusammenführt. -For now, we can see from the output that there is a single commit that John has made that Jessica has not merged in. -If she merges `origin/master`, that is the single commit that will modify her local work. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Jetzt kann Jessica ihren "issue54"-Branch mit ihrem `master`-Branch zusammenführen, danach Johns Arbeit (`origin/master`) mit ihrem `master`-Branch zusammenführen und dann das Ganze auf den Server hochladen. -Jetzt kann Jessica ihren Themenbranch mit ihrem `master`-Branch zusammenführen, danach Johns Arbeit (`origin/master`) mit ihrem `master`-Branch zusammenführen und dann das Ganze auf den Server hochladen. Zuerst wechselt sie zu ihrem `master`-Branch, um alle diese Änderungen zu integrieren: [source,console] @@ -353,7 +288,7 @@ Fast forward ---- Es treten keine Probleme auf; wie Sie sehen können, war es ein einfacher "Fast-Forward". -Nun integriert Jessica die Arbeit von John (`origin/master`): +Jessica vervollständigt nun den lokalen Merge-Prozess, indem sie Johns früher geholte Arbeit zusammenführt, die im Branch `origin/master` liegt: [source,console] ---- @@ -384,22 +319,15 @@ Jeder Entwickler hat einige Commits durchgeführt und jeweils die Arbeiten des a .Jessicas Verlauf nach dem Hochladen aller Änderungen auf den Server. image::images/small-team-7.png[Jessica's history after pushing all changes back to the server.] -<<<<<<< HEAD Das ist einer der einfachsten Arbeitsabläufe. Sie arbeiten eine Weile, gewöhnlich an einem Themenbranch, und führen diesen mit ihrem master-Branch zusammen, wenn dieser soweit fertig ist, dass er integriert werden kann. Wenn Sie diese Arbeit mit anderen teilen wollen, führen Sie die Änderungen mit ihrem eigenen `master`-Branch zusammen, holen eventuelle Änderungen vom Branch `origin/master` ab und führen diese mit ihren `master`-Branch zusammen, und schließlich laden sie alles auf den `master`-Branch auf den Server hoch. Der generelle Ablauf sieht ungefähr so aus: -======= -That is one of the simplest workflows. -You work for a while, generally in a topic branch, and merge into your `master` branch when it's ready to be integrated. -When you want to share that work, you fetch and merge your `master` from `origin/master` if it has changed, and finally push to the `master` branch on the server. -The general sequence is something like this: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 .Genereller Ablauf von Ereignissen für einen einfachen Arbeitsablauf mit mehreren Entwicklern. image::images/small-team-flow.png[General sequence of events for a simple multiple-developer Git workflow.] -==== Geführte vertrauliche Teams +==== Geführte private Teams (((contributing, private managed team))) In diesem Szenario werden Sie die Funktionen von Mitarbeitern in einem größeren, nicht öffentlich arbeitenden Team betrachten. @@ -435,15 +363,9 @@ To jessica@githost:simplegit.git * [new branch] featureA -> featureA ---- -<<<<<<< HEAD Jessica sendet John eine E-Mail, um ihm mitzuteilen, dass einige Änderungen auf einen neuen Branch namens `featureA` hochgeladen hat und er nun einen Blick darauf werfen kann. Während sie auf ein Feedback von John wartet, entscheidet sich Jessica, mit der Arbeit an `featureB` zu beginnen - diesmal gemeinsam mit Josie. -Am Anfang legt sie einen neuen Feature-Branch an, basierend auf dem `master`-Branch, welcher sich auf dem Server befindet (`origin/master`): -======= -Jessica emails John to tell him that she's pushed some work into a branch named `featureA` and he can look at it now. -While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. -To begin, she starts a new feature branch, basing it off the server's `master` branch: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Am Anfang legt sie einen neuen Feature-Branch an, basierend auf dem `master`-Branch, welcher sich auf dem Server befindet (`origin/master`): [source,console] ---- @@ -472,15 +394,9 @@ Jessicas Repository sieht jetzt so aus: .Jessicas ursprünglicher Commit-Verlauf. image::images/managed-team-1.png[Jessica's initial commit history.] -<<<<<<< HEAD Jessica könnte ihre Arbeit jetzt hochladen, aber sie bekommt eine E-Mail von Josie, in der diese mitteilt, dass bereits ein Branch namens `featureBee` hochgeladen wurde, welcher einige erste Änderungen beinhaltet. Jessica muss also erst diese Änderungen mit ihren eigenen Änderungen zusammenführen, bevor sie selbst etwas hochladen kann. Sie kann Josies Änderungen mit `git fetch` herunterladen: -======= -She's ready to push up her work, but gets an email from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. -Jessica first needs to merge those changes in with her own before she can push to the server. -She can then fetch Josie's changes down with `git fetch`: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 [source,console] ---- @@ -490,7 +406,7 @@ From jessica@githost:simplegit * [new branch] featureBee -> origin/featureBee ---- -Jessica kann jetzt dies mit den Änderungen, die sie vorgenommen hat, zusammenführen: +Angenommen, Jessica befindet sich noch in ihrem ausgecheckten `featureB` Branch und kann nun Josies Arbeit mit `git merge` in diesen Zweig einbinden: [source,console] ---- @@ -501,8 +417,8 @@ Merge made by the 'recursive' strategy. 1 files changed, 4 insertions(+), 0 deletions(-) ---- -Dabei gibt es ein kleines Problem - sie muss die zusammengeführten Änderungen in ihrem `featureB`-Branch in den `featureBee`-Branch auf dem Server hochladen. -Sie kann dies erledigen, indem sie die Anweisung `git push` verwendet und dabei den lokalen Branch festlegt, gefolgt von einem Doppelpunkt (:), gefolgt vom Branch auf dem entfernten Server: +Jetzt möchte Jessica alle zusammengeführten featureB-Arbeiten zurück auf den Server schieben, aber sie will nicht sie einfach ihren eigenen featureB-Zweig hochschieben. +Da Josie bereits einen Upstream-FeatureBee-Zweig gestartet hat, will Jessica zu diesem Branch hochladen, indem sie folgenden Befehl ausführt: [source,console] ---- @@ -513,16 +429,11 @@ To jessica@githost:simplegit.git ---- Das bezeichnet man als _refspec_. -Siehe <<_refspec>> für detailliertere Diskussionen von Gits refspecs und verschiedenden Dingen, die Sie damit machen können. -Beachten Sie auch die Option `-u`; das ist die Kurzform von `--set-upstream`, welche die Branches für ein einfacheres Hoch- und Herunterladen konfiguriert. +Siehe <> für eine ausführlichere Beschreibung der Git „refspecs“ und den unterschiedlichen Möglichkeiten, die Sie damit haben. +Beachten Sie auch das `-u` Flag, eine Abkürzung für `--set-upstream`, das die Branches für später leichtere Pushs und Pulls konfiguriert. -<<<<<<< HEAD -Als Nächstes sendet John eine E-Mail an Jessica, um sie zu informieren, dass er einige Änderungen auf den `featureA`-Branch hochgeladen hat, und um sie zu bitten, diese zu überprüfen. -Sie führt die Anweisung `git fetch` aus, um diese Änderungen herunter zu laden: -======= -Next, John emails Jessica to say he's pushed some changes to the `featureA` branch and asks her to verify them. -She runs a `git fetch` to pull down those changes: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Als Nächstes sendet John eine E-Mail an Jessica, um sie zu informieren, dass er einige Änderungen auf den `featureA`-Branch hochgeladen hat, und sie bittet, diese zu überprüfen. +Wieder Sie führt die Anweisung `git fetch` aus, um diese Änderungen herunter zu laden: [source,console] ---- @@ -532,7 +443,7 @@ From jessica@githost:simplegit 3300904..aad881d featureA -> origin/featureA ---- -Um zu sehen, was geändert wurde, benutzt sie die Anweisung `git log`: +Jessica kann sich das Protokoll von Johns neuer Arbeit anzeigen lassen indem sie den Inhalt des neu abgerufenen Branch `featureA` mit ihrer lokalen Kopie des gleichen Zweiges vergleicht: [source,console] ---- @@ -544,7 +455,7 @@ Date: Fri May 29 19:57:33 2009 -0700 changed log output to 30 from 25 ---- -Schließlich lässt sie Johns Änderungen in ihren eigenen `featureA`-Branch einfließen: +Wenn ihr Johns neue Arbeit gefällt, kann sie sie mit ihrem lokalen Branch `featureA` verschmelzen: [source,console] ---- @@ -557,7 +468,7 @@ Fast forward 1 files changed, 9 insertions(+), 1 deletions(-) ---- -Jessica möchte etwas optimieren, also führt sie wieder einen Commit durch und lädt dann das Ganze auf den Server hoch: +Schließlich möchte Jessica möglicherweise ein paar geringfügige Änderungen an dem gesamten zusammengeführten Inhalt vornehmen. Sie kann diese Änderungen vornehmen, sie in ihren lokalen Zweig 'featureA' übertragen und das Endergebnis zurück auf den Server übertragen: [source,console] ---- @@ -575,8 +486,8 @@ Jessicas Commit-Verlauf sieht jetzt ungefähr so aus: .Jessicas Verlauf nach dem Commit auf den Feature-Branch. image::images/managed-team-2.png[Jessica's history after committing on a feature branch.] -Jessica, Josie und John informieren die Integrationsmanager, dass die Branches `featureA` und `featureBee` auf dem Server soweit fertiggestellt sind, um in die Hauptlinie integriert zu werden. -Nachdem die Integrationsmanager diese Branches mit der Hauptlinie zusammengeführt haben, wird beim Abholen der Daten vom Server der neue Merge-Commit heruntergeladen, was den Commit-Verlauf dann so aussehen lässt: +Irgendwann informieren Jessica, Josie und John die Integratoren, dass die Zweige `featureA` und `featureBee` auf dem Server für die Integration in die Hauptlinie bereit sind. +Nachdem die Integratoren diese Branches in der Hauptlinie zusammengeführt haben, wird beim Abrufen das neue Merge-Commit beendet, sodass der Verlauf wie folgt aussieht: .Jessicas Verlauf nach dem Zusammenführen mit ihren beiden Themenbranches. image::images/managed-team-3.png[Jessica's history after merging both her topic branches.] @@ -592,58 +503,45 @@ image::images/managed-team-flow.png[Basic sequence of this managed-team workflow ==== Verteiltes öffentliches Projekt (((contributing, public small project))) -<<<<<<< HEAD An einem öffentlichen Projekt mitzuarbeiten, ist ein wenig anders. Da Sie keine Berechtigungen haben, die Branches des Projektes direkt zu aktualisieren, müssen Sie die Änderungen auf andere Art und Weise zu den Projektbetreibern bekommen. Dieses erste Beispiel beschreibt die Mitarbeit mittels "Forking" auf Git-Hosting-Servern, welche einfaches "Forking" unterstützen. -Viele Hosting-Websites unterstützen dies (einschließlich GitHub, BitBucket, Google Code repo.or.cz und andere), und viele Projektbetreiber erwarten diese Art der Zuarbeit. -Der nächste Abschnitt handelt von Projekten, welche die Abgabe von Patches bevorzugt via E-Mail akzeptieren. -======= -Contributing to public projects is a bit different. -Because you don't have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. -This first example describes contributing via forking on Git hosts that support easy forking. -Many hosting sites support this (including GitHub, BitBucket, repo.or.cz, and others), and many project maintainers expect this style of contribution. -The next section deals with projects that prefer to accept contributed patches via email. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Viele Hosting-Websites unterstützen dies (einschließlich GitHub, BitBucket, Google Code repo.or.cz und andere), und viele Projektbetreiber erwarten diese Art der Mitarbeit. +Der nächste Abschnitt handelt von Projekten, welche die Abgabe von Patches via E-Mail bevorzugt akzeptieren. Zunächst werden Sie vermutlich das Hauptrepository klonen wollen, einen Themenbranch anlegen für den Patch oder die Serie von Patches, die Sie beisteuern möchten, und dann darin arbeiten. Die Reihenfolge sieht dann in etwa so aus: [source,console] ---- -$ git clone (url) +$ git clone $ cd project $ git checkout -b featureA -# (work) + ... work ... $ git commit -# (work) + ... work ... $ git commit ---- [NOTE] ==== -Es empfiehlt sich, die Anweisung `git rebase -i` zu verwenden, um die verschiedenen Commits zu einem einzigen zusammenzufassen oder um sie in anderer Weise neu zu arrangieren, sodass es für die Projektbetreiber leichter ist, die Änderungen zu überprüfen- – siehe <<_rewriting_history>> für weitere Informationen über interaktives Rebasing. +Sie können `rebase -i` verwenden, um Ihre Arbeit auf einen einzelnen Commit zu reduzieren oder die Arbeit in den Commits neu anzuordnen damit der Patch für den Maintainer einfacher zu überprüfen ist – siehe <> für weitere Informationen über interaktives Rebasing. ==== -Wenn Sie mit der Arbeit an ihrem Branch fertig sind und Sie ihren Beitrag den Projektbetreibern zur Verfügung stellen wollen, gehen Sie auf die Projektseite und klicken auf den ``Fork''-Button, um Ihren eigenen Fork des Projektes anzulegen, in den Sie dann schreiben können. -Die URL des Repositorys dieses Forks müssen Sie dann als ein zweites, entferntes Repository (``remote'') einrichten, in diesem Beispiel hat es den Namen `myfork`: +Wenn Sie mit der Arbeit an ihrem Branch fertig sind und Sie ihren Beitrag den Projektbetreibern zur Verfügung stellen wollen, gehen Sie auf die Projektseite und klicken auf den „Fork“ Button, um Ihren eigenen Fork des Projektes anzulegen, in den Sie dann schreiben können. +Anschließend müssen Sie diese Repository-URL als neue Remote-Adresse Ihres lokalen Repositorys hinzufügen. Nennen wir es in diesem Beispiel `myfork`: [source,console] ---- -$ git remote add myfork (url) +$ git remote add myfork ---- -<<<<<<< HEAD Dann müssen Sie Ihre Änderungen dorthin hochladen. -Am einfachsten ist es, den Themenbranch, an dem Sie gerade arbeiten, in Ihr Repository hochzuladen, anstatt ihn mit Ihrem `master`-Branch zusammenzuführen und diesen dann hochzuladen. -Der Grund dafür ist, dass Sie Ihren `master`-Branch nicht zurücksetzen müssen, falls Ihre Änderungen nicht akzeptiert werden. +Es ist am einfachsten, den Themenbranch, an dem Sie arbeiten, in Ihr Forked-Repository hochzuladen, anstatt diese Arbeit in Ihrem Master-Zweig zusammenzuführen und dorthin zu verschieben. +Der Grund dafür ist, dass Sie Ihren `master` Branch nicht zurücksetzen müssen, wenn Ihre Arbeit nicht angenommen oder ausgewählt wurde (die Git-Operation `cherry-pick` zum Auswählen einzelner Commits wird in <> ausführlicher behandelt). Wenn die Projektbetreiber Ihre Änderungen übernehmen, ob mit `merge`, `rebase` oder `cherry-pick`, werden Sie diese schließlich sowieso zurückbekommen mittels `git pull` von deren Repository. -======= -Then you need to push your work up to it. -It's easiest to push the topic branch you're working on up to your repository, rather than merging into your master branch and pushing that up. -The reason is that if the work isn't accepted or is cherry-picked, you don't have to rewind your master branch. (`cherry-pick` is covered in more detail in <<_rebase_cherry_pick>>). -If the maintainers `merge`, `rebase`, or `cherry-pick` your work, you'll eventually get it back via pulling from their repository anyhow: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 + +Auf jeden Fall können Sie Ihre Arbeit voranbringen mit: [source,console] ---- @@ -651,22 +549,17 @@ $ git push -u myfork featureA ---- (((git commands, request-pull))) -<<<<<<< HEAD -Wenn Sie Ihre Arbeit in Ihren Fork hochgeladen haben, müssen Sie den Projektbetreiber benachrichtigen. -Dies wird häufig als ``pull request'' bezeichnet und Sie können diesen entweder direkt über die Webseite erzeugen - GitHub hat seinen eigenen ``Pull Request''-Mechanismus, welchen wir in <<_github>> näher betrachten - oder Sie können die Anweisung `git request-pull` ausführen und die Ausgabe manuell per E-Mail an den Projektbetreiber schicken. -======= -When your work has been pushed up to your fork, you need to notify the maintainer. -This is often called a pull request, and you can either generate it via the website – GitHub has its own Pull Request mechanism that we'll go over in <<_github>> – or you can run the `git request-pull` command and email the output to the project maintainer manually. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Sobald Ihre Arbeit auf Ihren Fork des Repository verschoben wurde, müssen Sie die Maintainer des ursprünglichen Projekts darüber informieren, dass Sie Arbeit haben, die Sie zusammenführen möchten. +Das wird oft als _pull request_ bezeichnet, und Sie generieren eine solche Anforderung typischerweise entweder über die Website – GitHub hat einen eigenen „Pull-Request“ Mechanismus, den wir im < durchgehen werden – oder Sie können den Befehl `git request-pull` ausführen und die nachfolgende Ausgabe manuell per E-Mail an den Projektbetreuer senden. -Die Anweisung `request-pull` nimmt den Ausgangsbranch, für den Ihre Änderungen bestimmt sind, und die URL des Git-Repositorys, von dem Ihre Änderungen heruntergeladen werden sollen, und gibt eine Zusammenfassung aller Änderungen aus, um deren Übernahme Sie bitten. -Wenn Jessica z. B. einen ``pull request'' an John schicken will, und sie zwei Commits auf dem gerade hochgeladenen Themenbranch durchgeführt hat, kann sie diese Anweisung ausführen: +Die Anweisung `git request-pull` verwendet den Ausgangsbranch, für den Ihre Änderungen bestimmt sind, und die URL des Git-Repositorys, von dem Ihre Änderungen heruntergeladen werden sollen, und gibt eine Zusammenfassung aller Änderungen aus, um deren Übernahme Sie bitten. +Wenn Jessica z.B. einen pull request an John schicken will, und sie zwei Commits auf dem gerade hochgeladenen Themenbranch durchgeführt hat, kann sie diese Anweisung ausführen: [source,console] ---- $ git request-pull origin/master myfork The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: - John Smith (1): +Jessica Smith (1): added a new function are available in the git repository at: @@ -681,34 +574,30 @@ Jessica Smith (2): 1 files changed, 9 insertions(+), 1 deletions(-) ---- -<<<<<<< HEAD -Die Ausgabe kann an die Projektbetreiber geschickt werden – sie sagt ihnen, auf welcher Stelle der Branch angelegt wurde, fasst die Commits zusammen und gibt an, aus welchem Fork oder Repository man die Änderungen herunterladen kann. -======= -The output can be sent to the maintainer – it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Diese Meldung kann an den Betreuer gesendet werden – sie teilt ihm mit, woher die Arbeit stammt, fasst die Commits zusammen und gibt an, von wo die neue Arbeit geholt werden soll. -Bei einem Projekt, wo Sie nicht selbst der Betreiber sind, ist es im Allgemeinen einfacher, einen Branch wie `master` zu haben, welcher immer den `origin/master`-Branch verfolgt, und Ihre eigenen Änderungen in Themenbranches vorzunehmen, die Sie leicht verwerfen können, wenn diese nicht akzeptiert werden. +Bei einem Projekt, für das Sie nicht der Betreuer sind, ist es im Allgemeinen einfacher, einen Branch wie `master` zu haben, welcher immer dem `origin/master` Branch folgt, und Ihre eigenen Änderungen in Themenbranches vorzunehmen, die Sie leicht verwerfen können, wenn diese nicht akzeptiert werden. Wenn Sie Schwerpunkte Ihrer Arbeit in Themenbranches unterteilen, können Sie diese außerdem recht leicht auf den letzten Stand des Hauptrepositorys rebasen, falls das Hauptrepository in der Zwischenzeit weiter entwickelt wurde und Ihre Commits sich nicht mehr sauber anwenden lassen. -Wollen Sie beispielsweise Änderungen zu einem weiteren Thema für das Projekt beisteuern, dann arbeiten Sie nicht weiter auf dem Themenbranch, den Sie gerade hochgeladen haben - sondern beginnen Sie von vorn vom `master`-Branch des Hauptrepositorys: +Wollen Sie beispielsweise Änderungen zu einem weiteren Thema dem Projekt beisteuern, dann arbeiten Sie nicht weiter auf dem Themenbranch, den Sie gerade hochgeladen haben - sondern beginnen Sie von vorn vom `master` Branch des Hauptrepositorys: [source,console] ---- $ git checkout -b featureB origin/master -# (work) + ... work ... $ git commit $ git push myfork featureB $ git request-pull origin/master myfork -# (email maintainer) + ... email generated request pull to maintainer ... $ git fetch origin ---- -Jedes Ihrer Themen befindet sich jetzt in einer Art Silo - ähnlich zu einer Patch Queue – sodass Sie diese neu schreiben, rebasen und ändern können, ohne dass die Themen sich gegemseitig stören oder voneinander abhängen: +Jedes Ihrer Themen befindet sich jetzt in einer Art Silo – ähnlich einer Patch Queue – sodass Sie diese neu schreiben, rebasen und ändern können, ohne dass die Branches sich gegemseitig stören oder voneinander abhängen: .Ursprünglicher Commit-Verlauf bei der Arbeit an `featureB`. image::images/public-small-1.png[Initial commit history with `featureB` work.] -Sagen wir, der Projektbetreiber hat eine Menge von anderen Patches übernommen und versucht, Ihren ersten Branch einfließen zu lassen, aber dieser lässt sich nicht mehr sauber anwenden. -In diesem Fall können Sie Ihre Änderungen auf dem letzten Stand des `origin/master`-Branches mittels Rebase hinzufügen, die Konflikte für den Projektbetreiber beheben und Ihre Arbeit erneut einreichen: +Nehmen wir an, der Projektbetreiber hat eine Menge von anderen Patches übernommen und versucht, Ihren ersten Branch einfließen zu lassen, aber dieser lässt sich nicht mehr sauber anwenden. +In diesem Fall können Sie Ihre Änderungen auf dem letzten Stand des `origin/master` Branch mittels Rebase hinzufügen, die Konflikte für den Projektbetreiber beheben und Ihre Arbeit erneut einreichen: [source,console] ---- @@ -727,28 +616,22 @@ Da Sie den Branch mittels Rebase hinzugefügt haben, müssen Sie die Anweisung ` Eine Alternative dazu wäre, diese neuen Änderungen in einen anderen Branch auf dem Server hochzuladen (vielleicht namens `featureAv2`). Schauen wir uns noch ein weiteres mögliches Szenario an: der Projektbetreiber hat sich Ihre Arbeit in Ihrem zweiten Branch angesehen und mag das Konzept, aber er bittet Sie, noch ein Detail an der Implementierung zu ändern. -Sie werden die Gelegenheit außerdem nutzen, um Ihre Änderungen zu verschieben, damit diese auf dem aktuellen `master`-Branch des Projektes basieren. -Sie legen dazu ausgehend vom aktuellen `origin/master`-Branch einen neuen Branch an, führen Ihre Änderungen aus `featureB` damit zusammen, lösen dabei jegliche Konflikte, erledigen die gewünschte Änderung an der Implementierung und laden das Ganze als neuen Branch hoch: +Sie werden die Gelegenheit außerdem nutzen, um Ihre Änderungen zu verschieben, damit diese auf dem aktuellen `master` Branch des Projektes basieren. +Sie legen dazu ausgehend vom aktuellen `origin/master` Branch einen neuen Branch an, führen Ihre Änderungen aus `featureB` damit zusammen, lösen dabei jegliche Konflikte, erledigen die gewünschte Änderung an der Implementierung und laden das Ganze als neuen Branch hoch: (((git commands, merge, squash))) [source,console] ---- $ git checkout -b featureBv2 origin/master $ git merge --squash featureB -# (change implementation) + ... change implementation ... $ git commit $ git push myfork featureBv2 ---- -<<<<<<< HEAD -Die Option `--squash` fasst alle Änderungen des einfließenden Branches (featureB) zusammen und quetscht diese in einen Nicht-Merge-Commit an der Spitze des Branches, auf dem Sie sich gerade befinden. +Die Option `--squash` fasst alle Änderungen des einfließenden Branches (featureB) zusammen und komprimiert sie in ein Change-Set, das den Zustand des Repositorys erzeugt, als ob ein echter Merge stattgefunden hätte, ohne tatsächlich einen Merge Commit zu machen. +Das bedeutet, dass Ihr zukünftiger Commit nur einen Elternteil hat und Ihnen ermöglicht, sämtliche Änderungen aus einem anderen Branch zu übernehmen und dann weitere Änderungen vorzunehmen, bevor Sie einen neuen Commit aufzeichnen. Die Option `--no-commit` weist Git außerdem an, nicht automatisch einen Commit anzulegen. -Das ermöglicht Ihnen, sämtliche Änderungen aus einem anderen Branch zu übernehmen und dann weitere Änderungen vorzunehmen, bevor Sie einen neuen Commit aufzeichnen. -======= -The `--squash` option takes all the work on the merged branch and squashes it into one changeset producing the repository state as if a real merge happened, without actually making a merge commit. -This means your future commit will have one parent only and allows you to introduce all the changes from another branch and then make more changes before recording the new commit. -Also the `--no-commit` option can be useful to delay the merge commit in case of the default merge process. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 Jetzt können Sie dem Projektbetreiber eine Nachricht schicken, dass Sie die gewünschten Änderungen vorgenommen haben und dass er Ihre Änderungen in Ihrem `featureBv2`-Branch finden kann. @@ -756,45 +639,29 @@ Jetzt können Sie dem Projektbetreiber eine Nachricht schicken, dass Sie die gew image::images/public-small-3.png[Commit history after `featureBv2` work.] [[_project_over_email]] -<<<<<<< HEAD ==== Öffentliches Projekt via E-Mail -======= -==== Public Project over Email ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 (((contributing, public large project))) -Viele Projekte haben festgelegte Verfahren, um Patches entgegenzunehmen - Sie werden sich mit den jeweiligen Regeln vertraut machen müssen, da diese bei jedem Projekt unterschiedlich sein werden. -Da ist etliche ältere, große Projekte gibt, welche Patches über eine Mailingliste der Entwickler entgegennehmen, werden wir auf dieses Beispiel als Nächstes eingehen. +Viele Projekte haben festgelegte Verfahren, um Patches entgegenzunehmen – Sie werden sich mit den jeweiligen Regeln vertraut machen müssen, da diese bei jedem Projekt unterschiedlich sein werden. +Da es etliche ältere, große Projekte gibt, welche Patches über eine Mailingliste der Entwickler entgegennehmen, werden wir auf dieses Beispiel als Nächstes eingehen. -<<<<<<< HEAD -Der Arbeitsablauf ist ähnlich dem im vorherigen Anwendungsfall - Sie erzeugen Themenbranches für jede Patchserie, an der Sie arbeiten. +Der Arbeitsablauf ist ähnlich dem im vorherigen Anwendungsfall – Sie erzeugen Themenbranches für jede Patchserie, an der Sie arbeiten. Der Unterschied besteht dann darin, wie Sie die Änderungen an das Projekt übermitteln. Anstatt das Projekt zu forken und Änderungen in Ihren Fork hochzuladen, erzeugen Sie E-Mail-Versionen von jeder Ihrer Commit-Folgen und senden diese an die Mailingliste der Entwickler. -======= -The workflow is similar to the previous use case – you create topic branches for each patch series you work on. -The difference is how you submit them to the project. -Instead of forking the project and pushing to your own writable version, you generate email versions of each commit series and email them to the developer mailing list: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 [source,console] ---- $ git checkout -b topicA -# (work) + ... work ... $ git commit -# (work) + ... work ... $ git commit ---- (((git commands, format-patch))) -<<<<<<< HEAD Jetzt haben Sie zwei Commits, die Sie an die Mailingliste schicken wollen. Sie verwenden die Anweisung `git format-patch`, um die Dateien im mbox-Format zu erzeugen, die Sie per E-Mail an die Mailingliste schicken können - diese Anweisung macht aus jedem Commit eine E-Mail-Nachricht, wobei die erste Zeile der Commit-Nachricht zum Betreff der E-Mail wird und der Rest der Commit-Nachricht sowie der Patch des Commits selbst wird zum Text der E-Mail. Das Schöne daran ist, dass bei der Anwendung eines Patches von einer mit `format-patch` erzeugten E-Mail alle Commit-Informationen ordnungsgemäß erhalten bleiben. -======= -Now you have two commits that you want to send to the mailing list. -You use `git format-patch` to generate the mbox-formatted files that you can email to the list – it turns each commit into an email message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. -The nice thing about this is that applying a patch from an email generated with `format-patch` preserves all the commit information properly. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 [source,console] ---- @@ -838,27 +705,17 @@ index 76f47bc..f9815f1 100644 2.1.0 ---- -<<<<<<< HEAD Sie können diese Patch-Dateien auch bearbeiten, um weitere Informationen für die Mailingliste hinzuzufügen, die nicht in der Commit-Nachricht erscheinen sollen. Wenn Sie Text zwischen der `---` Zeile und dem Anfang des Patches (der Zeile `diff --git`) hinzufügen, dann können die Entwickler diesen lesen, bei der Anwendung des Patches wird er aber ausgeschlossen. Um das jetzt an eine Mailingliste zu schicken, können Sie die Datei entweder in Ihrem E-Mail Programm einfügen oder sie über ein Befehlszeilen-Programm direkt verschicken. -Das Einfügen des Textes verursacht oft Formatierungsprobleme – insbesondere mit ``smarten'' E-Mail-Clients, welche Zeilenumbrüche und Leerzeichen nicht adäquat erhalten. -Zum Glück bringt Git aber ein Tool mit, was Ihnen dabei behilflich ist, ordnungsgemäß formatierte Patches über IMAP zu verschicken, was einfacher für Sie sein könnte. +Das Einfügen des Textes verursacht oft Formatierungsprobleme – insbesondere mit „smarten“ E-Mail-Clients, welche Zeilenumbrüche und Leerzeichen nicht adäquat erhalten. +Glücklicherweise bietet Git ein Tool, das Ihnen hilft, ordnungsgemäß formatierte Patches über IMAP zu verschicken, was einfacher für Sie sein könnte. Wir werden demonstrieren, wie man Patches über Gmail verschickt, welches der E-Mail-Client ist, mit dem wir uns am besten auskennen; Sie können detaillierte Anleitungen für eine Reihe von E-Mail-Programme am Ende der schon erwähnten Datei `Documentation/SubmittingPatches` im Git Quellcode nachlesen. -======= -You can also edit these patch files to add more information for the email list that you don't want to show up in the commit message. -If you add text between the `---` line and the beginning of the patch (the `diff --git` line), then developers can read it; but applying the patch excludes it. - -To email this to a mailing list, you can either paste the file into your email program or send it via a command-line program. -Pasting the text often causes formatting issues, especially with ``smarter'' clients that don't preserve newlines and other whitespace appropriately. -Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. -We'll demonstrate how to send a patch via Gmail, which happens to be the email agent we know best; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 (((git commands, config)))(((email))) -Zunächst müssen Sie den Abschnitt IMAP in Ihrer `~/.gitconfig`-Datei einrichten. -Sie können jeden Wert separat mit einer Reihe von `git config`-Anweisungen eingeben oder die Datei öffnen und die Werte manuell eingeben, am Ende sollte Ihre config-Datei in etwa so aussehen: +Zunächst müssen Sie den Abschnitt IMAP in Ihrer `~/.gitconfig` Datei einrichten. +Sie können jeden Wert separat mit einer Reihe von `git config` Anweisungen eingeben oder die Datei öffnen und die Werte manuell eingeben, am Ende sollte Ihre config-Datei in etwa so aussehen: [source,ini] ---- @@ -866,18 +723,13 @@ Sie können jeden Wert separat mit einer Reihe von `git config`-Anweisungen eing folder = "[Gmail]/Drafts" host = imaps://imap.gmail.com user = user@gmail.com - pass = p4ssw0rd + pass = YX]8g76G_2^sFbd port = 993 sslverify = false ---- -<<<<<<< HEAD Wenn Ihr IMAP-Server kein SSL verwendet, sind die letzten beiden Zeilen wahrscheinlich nicht nötig und der Host-Wert müsste `imap://` statt `imaps://` lauten. Wenn Sie diese Einstellungen vorgenommen haben, können Sie `git send-email` verwenden, um die Patches im Entwurfsordner des angegebenen IMAP-Servers zu platzieren: -======= -If your IMAP server doesn't use SSL, the last two lines probably aren't necessary, and the host value will be `imap://` instead of `imaps://`. -When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server: ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 [source,console] ---- @@ -934,16 +786,10 @@ In-Reply-To: References: Result: OK -<<<<<<< HEAD ------ - -Jetzt sollten Sie in der Lage sein, zum Entwurfsordner Ihres E-Mail-Clients zu gehen, als Empfänger die Adresse der Mailingliste anzugeben, an die Sie den Patch senden wollen, möglicherweise den Projektbetreiber oder einen anderen Verantwortlichen auf CC zu setzen und die E-Mail dann zu verschicken. -======= ---- ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 ==== Zusammenfassung Dieser Abschnitt hat eine Reihe von gebräuchlichen Arbeitsabläufen behandelt, die für jeweils sehr verschiedene Arten von Projekten üblich sind und denen Du vermutlich begegnen wirst. Wir haben außerdem ein paar neue Tools vorgestellt, die dabei hilfreich sind, diese Workflows umzusetzen. Als nächstes werden wir auf die andere Seite dieser Medaille eingehen: wie Sie selbst ein Git Projekt betreiben können. -Sie werden erfahren, wie Sie als „wohlwollender Diktator“ oder als Integrationsmanager arbeiten können. \ No newline at end of file +Sie werden erfahren, wie Sie als „wohlwollender Diktator“ oder als Integrationsmanager arbeiten können. diff --git a/book/05-distributed-git/sections/distributed-workflows.asc b/book/05-distributed-git/sections/distributed-workflows.asc index c64218a9b..c0a96f4f2 100644 --- a/book/05-distributed-git/sections/distributed-workflows.asc +++ b/book/05-distributed-git/sections/distributed-workflows.asc @@ -1,114 +1,80 @@ -=== Verteilte Arbeitsabläufe +=== Verteilter Arbeitsablauf (((workflows))) -Im Gegensatz zu zentralisierten Versionsverwaltungen (CVCSs) ermöglicht Ihnen der dezentrale Charakter von Git, sehr viel flexibler darin zu sein, wie die Entwicklern bei Projekten zusammenarbeiten. -In zentralisierten Systemen fungieren alle Entwickler als gleichwertige Netzknoten, die mehr oder weniger in der gleichen Art und Weise an einem zentralen Knotenpunkt arbeiten. -In Git dagegen ist jeder Entwickler potentiell beides - Netzknoten und zentraler Knotenpunkt, d. h. jeder Entwickler kann sowohl Code zu anderen Repositories beitragen als auch selbst ein öffentliches Repository unterhalten, auf welchem widerum andere Ihre Arbeit aufbauen und an dem sie mitarbeiten können. -Das eröffnet eine Fülle von möglichen Arbeitsabläufen für Ihr Projekt, weshalb wir einige gebräuchliche Musterbeispiele betrachten werden, welche sich diese Flexibilität zu Nutze machen. +Im Gegensatz zu CVCSs (Centralized Version Control Systems) können Sie dank der verteilten Struktur von Git die Zusammenarbeit von Entwicklern in Projekten wesentlich flexibler gestalten. +In zentralisierten Systemen fungieren alle Entwickler als gleichwertige Netzknoten, die mehr oder weniger in der gleichen Art und Weise an einem zentralen Hub arbeiten. +In Git dagegen ist jeder Entwickler potentiell beides – Netzknoten und zentraler Hub, d.h. jeder Entwickler kann sowohl Code zu anderen Repositories beitragen als auch selbst ein öffentliches Repository unterhalten, auf welchem wiederum andere Ihre Arbeit aufbauen und an dem sie mitarbeiten können. +Das eröffnet eine Fülle von möglichen Arbeitsabläufen (engl. Workflows) für Ihr Projekt, weshalb wir einige gängige Verfahren behandeln werden, die diese Flexibilität nutzen. Wir werden auf die Stärken und möglichen Schwächen der einzelnen Entwürfe eingehen; Sie können einen einzelnen davon auswählen, um ihn zu nutzen, oder Sie können die Funktionalitäten von allen miteinander kombinieren. -==== Zentralisierte Arbeitsabläufe +==== Zentralisierter Arbeitsablauf (((workflows, centralized))) -In einem zentralisierten System gibt es im Allgemeinen ein einziges Modell der Zusammenarbeit - der zentralisierte Arbeitsablauf. -Ein zentraler Knotenpunkt (oder Repository) kann Code von anderen akzeptieren und übernehmen, und alle Beteiligten synchronisieren ihre Arbeit damit. -Eine Reihe von Entwicklern sind Netzknoten - Abnehmer von diesem Knotenpunkt - und synchronisieren ihre Arbeit mit diesem einen, zentralen Punkt. +In einem zentralisierten System gibt es im Allgemeinen ein einziges Modell für die Zusammenarbeit – der zentralisierte Workflow. +Ein zentraler Hub (oder _Repository_) kann Code von anderen akzeptieren und übernehmen, und alle Beteiligten synchronisieren ihre Arbeit damit. +Eine Reihe von Entwicklern sind Netzknoten – Abnehmer von diesem Hub – und synchronisieren ihre Arbeit mit diesem einen, zentralen Punkt. -.Zentralisierter Arbeitsablauf. +.Zentralisierter Workflow. image::images/centralized_workflow.png[Zentralisierter Arbeitsablauf.] Das bedeutet, wenn zwei Entwickler ein Repository vom zentralen Knotenpunkt klonen und beide lokal Änderungen vornehmen, dann kann der Entwickler, welcher als erster seine Änderungen ins zentrale Repository hochladen möchte, dies ohne Probleme tun. Der zweite Entwickler muss jedoch zunächst die Änderungen des ersten Entwicklers bei sich einfließen lassen, bevor er seine eigenen Änderungen hochladen kann, damit er die Änderungen des ersten Entwicklers nicht überschreibt. -Dieses Prinzip ist sowohl für Git zutreffend als auch für Subversion(((Subversion))) (oder irgendein CVCS), und dieses Modell funktioniert bei Git vollkommen einwandfrei. +Dieses Prinzip gilt sowohl für Git als auch für Subversion(((Subversion))) (oder irgendein anderes CVCS). Das Konzept funktioniert bei Git perfekt. Wenn Sie in Ihrer Firma oder in Ihrem Team bereits mit einem zentralisierten Arbeitsablauf vertraut sind, können Sie einfach so weitermachen und diesen Arbeitsablauf mit Git realisieren. Richten Sie einfach ein einziges Repository ein und geben Sie jedem in Ihrem Team Schreibzugriff („push access“). Git sorgt dann dafür, dass niemand die Arbeit von anderen überschreiben kann. -Sagen wir, Jessica und John beginnen mit der Arbeit zur selben Zeit. + +Angenommen, John und Jessica beginnen gleichzeitig mit der Arbeit. John beendet seine Änderungen und lädt diese auf den Server hoch. Dann versucht Jessica, ihre Änderungen hochzuladen, aber der Server weist diese zurück. -Ihr wird mitgeteilt, dass sie versucht hat, ``non-fast-forward''-Änderungen hochzuladen und dass sie dazu nicht in der Lage ist, bevor sie nicht die Änderungen des anderen Entwicklers heruntergeladen und mit ihren zusammengeführt hat. -Viele Leute mögen diesen Arbeitsablauf, weil sie mit dem Paradigma bereits vertraut sind und sich damit wohl fühlen. +Ihr wird mitgeteilt, dass sie versucht hat „non-fast-forward“ Änderungen hochzuladen und dass sie das erst dann durchführen kann, wenn sie zuvor vorhandene andere Änderungen geholt und zusammengeführt hat. +Viele Anwender mögen diesen Arbeitsablauf, weil sie mit dem bewährten Modell bereits vertraut sind und es bequem ist. -<<<<<<< HEAD -Dies ist auch nicht auf kleine Teams beschränkt. Mit dem Branching-Modell von Git ist es möglich, dass hunderte von Entwicklern an einem einzelnen Projekt mittels dutzenden von Branches gleichzeitig erfolgreich arbeiten. -======= -This is also not limited to small teams. -With Git's branching model, it's possible for hundreds of developers to successfully work on a single project through dozens of branches simultaneously. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +Das gilt nicht nur für kleine Teams. +Mit dem Branching-Modell von Git ist es Hunderten von Entwicklern möglich, an einem einzelnen Projekt, über Dutzende von Branches, gleichzeitig erfolgreich zu arbeiten. [[_integration_manager]] ==== Arbeitsablauf mit Integrationsmanager (((workflows, integration manager))) -<<<<<<< HEAD -Weil Git es Ihnen ermöglicht, mehrere entfernte Repositories zu betreiben, ist es möglich, einen Arbeitsablauf zu gestalten, in dem jeder Entwickler Schreibzugriff auf sein eigenes öffentliches Repository hat und Lesezugriff auf die Repositories von allen anderen. -Dieses Szenario beinhaltet häufig ein anerkanntes Repository, welches das ``offizielle'' Projekt darstellt. +Da Git es Ihnen ermöglicht, mehrere Remote-Repositorys zu betreiben, ist ein Workflow möglich, bei dem jeder Entwickler Schreibzugriff auf sein eigenes öffentliches Repository und Lesezugriff auf alle anderen hat. +Dieses Szenario beinhaltet häufig ein eigens dafür eingerichtetes Repository, welches das „offizielle“ Projekt darstellt. Um Änderungen zu einem solchen Projekt beizusteuern, können Sie Ihren eigenen öffentlichen Klon des Projektes anlegen und Ihre Änderungen dorthin hochladen. Anschließend können Sie den Betreiber des Haupt-Repositories bitten, Ihre Änderungen in sein Repository zu übernehmen. Der Betreiber kann dann Ihr Repository als ein entferntes Repository auf seinem Rechner hinzufügen, Ihre Änderungen lokal testen, diese in einen seiner Branches einfließen lassen und dann in sein öffentliches Repository hochladen. Dieser Prozess läuft wie folgt ab (siehe <>): 1. Der Projektbetreiber lädt in sein öffentliches Repository hoch. -2. Ein Mitarbeiter klont das Repository und nimmt Änderungen daran vor. -3. Der Mitarbeiter lädt diese in sein eigenes öffentliches Repository hoch. -4. Der Mitarbeiter schickt dem Betreiber eine E-Mail und bittet darum, die Änderungen zu übernehmen. -5. Der Betreiber fügt das Repository des Mitarbeiters als ein entferntes Repository hinzu und führt die Änderungen lokal zusammen. -6. Der Betreiber lädt die zusammengeführten Änderungen in das Haupt-Repository hoch. -======= -Because Git allows you to have multiple remote repositories, it's possible to have a workflow where each developer has write access to their own public repository and read access to everyone else's. -This scenario often includes a canonical repository that represents the ``official'' project. -To contribute to that project, you create your own public clone of the project and push your changes to it. -Then, you can send a request to the maintainer of the main project to pull in your changes. -The maintainer can then add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. -The process works as follows (see <>): - -1. The project maintainer pushes to their public repository. -2. A contributor clones that repository and makes changes. -3. The contributor pushes to their own public copy. -4. The contributor sends the maintainer an email asking them to pull changes. -5. The maintainer adds the contributor's repo as a remote and merges locally. -6. The maintainer pushes merged changes to the main repository. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +2. Ein Mitwirkender klont dieses Repository und nimmt Änderungen vor. +3. Der Beitragende lädt diese in sein eigenes öffentliches Repository hoch. +4. Der Beitragende schickt dem Betreiber eine E-Mail und bittet darum, die Änderungen zu übernehmen. +5. Der Betreuer fügt das Repository des Beitragenden als ein Remote-Repository hinzu und führt die Änderungen lokal zusammen. +6. Der Betreuer lädt die zusammengeführten Änderungen in das Haupt-Repository hoch. [[wfdiag_b]] .Arbeitsablauf mit Integrationsmanager. image::images/integration-manager.png[Arbeitsablauf mit Integrationsmanager.] (((forking))) -Dies ist ein sehr gewöhnlicher Arbeitsablauf bei hub-basierten Werkzeugen wie GitHub oder GitLab, wo es sehr einfach ist, ein Projekt zu ``forken'' und Ihre Änderungen in Ihren eigenen Fork hochzuladen, wo diese jeder einsehen kann. +Das ist ein sehr verbreiteter Workflow bei hub-basierten Werkzeugen wie GitHub oder GitLab, wo es sehr einfach ist, ein Projekt zu „forken“ und Ihre Änderungen in Ihren eigenen Fork hochzuladen, wo jeder sie sehen kann. Einer der Hauptvorteile dieser Vorgehensweise ist, dass Sie an Ihrem Fork weiterarbeiten können und der Betreiber des Haupt-Repositorys Ihre Änderungen jederzeit übernehmen kann. Mitarbieter müssen nicht darauf warten, dass der Betreiber ihre Änderungen einarbeitet – jeder Beteiligte kann in seinem eigenen Tempo arbeiten. ==== Arbeitsablauf mit Diktator und Leutnants (((workflows, dictator and lieutenants))) -<<<<<<< HEAD Dies ist eine Variante eines Arbeitsablaufs mit vielen Repositories. Sie wird normalerweise bei sehr großen Projekten mit hunderten von Mitarbeitern verwendet; ein bekanntes Beispiel ist der Linux Kernel. -Verschiedene Integrationsmanager sind zuständig für bestimmte Teile des Repositorys; sie werden Leutnants genannt. +Verschiedene Integrationsmanager sind zuständig für bestimmte Teile des Repositorys; sie werden _Leutnants_ genannt. Alle Leutnants haben wiederum einen Integrationsmanager, der als der wohlwollende Diktator (benevolent dictator) bezeichnet wird. -Das Repository des wohlwollenden Diktators dient als das Referenzrepository, aus dem alle Beteiligten ihre eigenen Repositories aktualisieren müssen. +Der wohlwollende Diktator pusht von seinem Verzeichnis zu einem Referenz-Repository, aus dem alle Beteiligten ihre eigenen Repositories aktualisieren müssen. Dieser Prozess funktioniert wie folgt (siehe <>): -1. Normale Entwickler arbeiten an ihren Themenbranches und fügen Ihre Arbeit an der Spitze des `master`-Branches mittels Rebase ein. - Der `master`-Branch ist der Branch des Diktators. -2. Die Leutnants führen die Themenbranches der Entwickler mit ihren `master`-Branches zusammen. -3. Der Diktator führen die `master`-Branches der Leutnants mit seinem eigenen `master`-Branch zusammen. -4. Der Diktator lädt seinen `master`-Branch ins Referenzrepository hoch, damit die anderen Entwickler darauf Rebase durchführen können. -======= -This is a variant of a multiple-repository workflow. -It's generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. -Various integration managers are in charge of certain parts of the repository; they're called lieutenants. -All the lieutenants have one integration manager known as the benevolent dictator. -The benevolent dictator pushes from his directory to a reference repository from which all the collaborators need to pull. -The process works like this (see <>): - -1. Regular developers work on their topic branch and rebase their work on top of `master`. - The `master` branch is that of the reference directory to which the dictator pushes. -2. Lieutenants merge the developers' topic branches into their `master` branch. -3. The dictator merges the lieutenants' `master` branches into their `master` branch. -4. The dictator pushes their `master` to the reference repository so the other developers can rebase on it. ->>>>>>> 811dffebd4ff1348819f8acc70f954bd4ad65057 +1. Normale Entwickler arbeiten an ihren Themenbranches und fügen Ihre Arbeit an der Spitze des `master` Branch mittels Rebase ein. + Der `master` Branch ist der des Referenz-Repositorys, in das der Diktator pusht. +2. Die Leutnants führen die Themenbranches der Entwickler mit ihren `master` Branches zusammen. +3. Der Diktator führt die `master`-Branches der Leutnants mit seinem eigenen `master`-Branch zusammen. +4. Der Diktator lädt seinen `master`-Branch ins Referenz-Repository hoch, damit die anderen Entwickler darauf einen Rebase durchführen können. [[wfdiag_c]] .Arbeitsablauf mit wohlwollendem Diktator. diff --git a/book/05-distributed-git/sections/maintaining.asc b/book/05-distributed-git/sections/maintaining.asc index 61caf0f0b..44cab8061 100644 --- a/book/05-distributed-git/sections/maintaining.asc +++ b/book/05-distributed-git/sections/maintaining.asc @@ -1,17 +1,17 @@ === Maintaining a Project (((maintaining a project))) -In addition to knowing how to effectively contribute to a project, you'll likely need to know how to maintain one. +In addition to knowing how to contribute effectively to a project, you'll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and emailed to you, or integrating changes in remote branches for repositories you've added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. ==== Working in Topic Branches (((branches, topic))) -When you're thinking of integrating new work, it's generally a good idea to try it out in a topic branch – a temporary branch specifically made to try out that new work. +When you're thinking of integrating new work, it's generally a good idea to try it out in a _topic branch_ -- a temporary branch specifically made to try out that new work. This way, it's easy to tweak a patch individually and leave it if it's not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you're going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. -The maintainer of the Git project tends to namespace these branches as well – such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +The maintainer of the Git project tends to namespace these branches as well -- such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you'll remember, you can create the branch based off your `master` branch like this: [source,console] @@ -38,7 +38,7 @@ There are two ways to apply an emailed patch: with `git apply` or with `git am`. ===== Applying a Patch with apply (((git commands, apply))) -If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command (which is not recommended; see the next section), you can apply it with the `git apply` command. +If you received the patch from someone who generated it with `git diff` or some variation of the Unix `diff` command (which is not recommended; see the next section), you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: [source,console] @@ -51,9 +51,9 @@ It's almost identical to running a `patch -p1` command to apply the patch, altho It also handles file adds, deletes, and renames if they're described in the `git diff` format, which `patch` won't do. Finally, `git apply` is an ``apply all or abort all'' model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more conservative than `patch`. -It won't create a commit for you – after running it, you must stage and commit the changes introduced manually. +It won't create a commit for you -- after running it, you must stage and commit the changes introduced manually. -You can also use `git apply` to see if a patch applies cleanly before you try actually applying it – you can run `git apply --check` with the patch: +You can also use `git apply` to see if a patch applies cleanly before you try actually applying it -- you can run `git apply --check` with the patch: [source,console] ---- @@ -87,12 +87,11 @@ Subject: [PATCH 1/2] add limit to log function Limit log functionality to the first 20 ---- -This is the beginning of the output of the `format-patch` command that you saw in the previous section. -This is also a valid mbox email format. +This is the beginning of the output of the `git format-patch` command that you saw in the previous section; it also represents a valid mbox email format. If someone has emailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several emails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time. -However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: +However, if someone uploaded a patch file generated via `git format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: [source,console] ---- @@ -138,7 +137,7 @@ To restore the original branch and stop patching run "git am --abort". ---- This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. -You solve this issue much the same way – edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: +You solve this issue much the same way -- edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: [source,console] ---- @@ -150,7 +149,7 @@ Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn't on by default because it doesn't work if the commit the patch says it was based on isn't in your repository. -If you do have that commit – if the patch was based on a public commit – then the `-3` option is generally much smarter about applying a conflicting patch: +If you do have that commit -- if the patch was based on a public commit -- then the `-3` option is generally much smarter about applying a conflicting patch: [source,console] ---- @@ -202,7 +201,7 @@ If she emails you again later with another branch containing another great featu This is most useful if you're working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over email may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You're also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. -However, scripts and hosted services may make this easier – it depends largely on how you develop and how your contributors develop. +However, scripts and hosted services may make this easier -- it depends largely on how you develop and how your contributors develop. The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. @@ -264,7 +263,7 @@ For example, if you've added a line in a file on the `master` branch, a direct c If `master` is a direct ancestor of your topic branch, this isn't a problem; but if the two histories have diverged, the diff will look like you're adding all the new stuff in your topic branch and removing everything unique to the `master` branch. -What you really want to see are the changes added to the topic branch – the work you'll introduce if you merge this branch with master. +What you really want to see are the changes added to the topic branch -- the work you'll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: @@ -276,8 +275,15 @@ $ git merge-base contrib master $ git diff 36c7db ---- -However, that isn't convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. -In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you're on and its common ancestor with another branch: +or, more concisely: + +[source,console] +---- +$ git diff $(git merge-base contrib master) +---- + +However, neither of those is particularly convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. +In the context of the `git diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you're on and its common ancestor with another branch: [source,console] ---- @@ -297,10 +303,11 @@ You have a number of choices, so we'll cover a few of them. ===== Merging Workflows (((workflows, merging))) -One simple workflow is to merge the work into your `master` branch. +One basic workflow is to simply merge all that work directly into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. -When you have work in a topic branch that you've done or that someone has contributed and you've verified, you merge it into your master branch, delete the topic branch, and then continue the process. -If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like <> and merge `ruby_client` first and then `php_client` next, then your history will end up looking like <>. +When you have work in a topic branch that you think you've completed, or work that someone else has contributed and you've verified, you merge it into your master branch, delete that just-merged topic branch, and repeat. + +For instance, if we have a repository with work in two branches named `ruby_client` and `php_client` that looks like <>, and we merge `ruby_client` followed by `php_client`, your history will end up looking like <>. [[merwf_a]] .History with several topic branches. @@ -329,7 +336,7 @@ image::images/merging-workflows-4.png[After a topic branch merge.] .After a project release. image::images/merging-workflows-5.png[After a topic branch release.] -This way, when people clone your project's repository, they can either check out `master` to build the latest stable version and keep up to date on that easily, or they can check out `develop`, which is the more cutting-edge stuff. +This way, when people clone your project's repository, they can either check out `master` to build the latest stable version and keep up to date on that easily, or they can check out `develop`, which is the more cutting-edge content. You can also extend this concept by having an `integrate` branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a `develop` branch; and when that has proven itself stable for a while, you fast-forward your `master` branch. @@ -356,7 +363,8 @@ image::images/large-merges-2.png[Merging contributed topic branches into long-te When a topic branch has finally been merged into `master`, it's removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. -The Git project's workflow is specialized. To clearly understand this you could check out the https://github.com/git/git/blob/master/Documentaion/howto/maintain-git.txt[Git Maintainer's guide]. +The Git project's workflow is specialized. +To clearly understand this you could check out the https://github.com/git/git/blob/master/Documentation/howto/maintain-git.txt[Git Maintainer's guide]. [[_rebase_cherry_pick]] ===== Rebasing and Cherry-Picking Workflows @@ -399,7 +407,7 @@ Now you can remove your topic branch and drop the commits you didn't want to pul (((git commands, rerere)))(((rerere))) If you're doing lots of merging and rebasing, or you're maintaining a long-lived topic branch, Git has a feature called ``rerere'' that can help. -Rerere stands for ``reuse recorded resolution'' – it's a way of shortcutting manual conflict resolution. +Rerere stands for ``reuse recorded resolution'' -- it's a way of shortcutting manual conflict resolution. When rerere is enabled, Git will keep a set of pre- and post-images from successful merges, and if it notices that there's a conflict that looks exactly like one you've already fixed, it'll just use the fix from last time, without bothering you with it. This feature comes in two parts: a configuration setting and a command. @@ -415,14 +423,14 @@ Now, whenever you do a merge that resolves conflicts, the resolution will be rec If you need to, you can interact with the rerere cache using the `git rerere` command. When it's invoked alone, Git checks its database of resolutions and tries to find a match with any current merge conflicts and resolve them (although this is done automatically if `rerere.enabled` is set to `true`). There are also subcommands to see what will be recorded, to erase specific resolution from the cache, and to clear the entire cache. -We will cover rerere in more detail in <<_rerere>>. +We will cover rerere in more detail in <>. [[_tagging_releases]] ==== Tagging Your Releases (((tags)))(((tags, signing))) -When you've decided to cut a release, you'll probably want to drop a tag so you can re-create that release at any point going forward. -You can create a new tag as discussed in <<_git_basics_chapter>>. +When you've decided to cut a release, you'll probably want to assign a tag so you can re-create that release at any point going forward. +You can create a new tag as discussed in <>. If you decide to sign the tag as the maintainer, the tagging may look something like this: [source,console] @@ -478,7 +486,7 @@ Also, if you include instructions in the tag message, running `git show ` w (((build numbers)))(((git commands, describe))) Because Git doesn't have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. -Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you're describing: +In response, Git generates a string consisting of the name of the most recent tag earlier than that commit, followed by the number of commits since that tag, followed finally by a partial SHA-1 value of the commit being described (prefixed with the letter "g" meaning Git): [source,console] ---- @@ -488,10 +496,10 @@ v1.6.2-rc1-20-g8c5b85c This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. -If you're describing a commit that you have directly tagged, it gives you the tag name. +If you're describing a commit that you have directly tagged, it gives you simply the tag name. -The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you're using `git describe`, to ensure the commit is named properly when described. -You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. +By default, the `git describe` command requires annotated tags (tags created with the `-a` or `-s` flag); if you want to take advantage of lightweight (non-annotated) tags as well, add the `--tags` option to the command. +You can also use this string as the target of a `git checkout` or `git show` command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. [[_preparing_release]] @@ -530,7 +538,7 @@ It summarizes all the commits in the range you give it; for example, the followi [source,console] ---- $ git shortlog --no-merges master --not v1.0.1 -Chris Wanstrath (8): +Chris Wanstrath (6): Add support for annotated tags to Grit::Tag Add packed-refs annotated tag support. Add Grit::Commit#to_patch diff --git a/book/06-github/images/2fa-1.png b/book/06-github/images/2fa-1.png deleted file mode 100644 index 5abd7437a..000000000 Binary files a/book/06-github/images/2fa-1.png and /dev/null differ diff --git a/book/06-github/images/blink-pull-request-open copy.png b/book/06-github/images/blink-pull-request-open copy.png deleted file mode 100644 index 5e40c6d98..000000000 Binary files a/book/06-github/images/blink-pull-request-open copy.png and /dev/null differ diff --git a/book/06-github/images/blink-pull-request-open.png b/book/06-github/images/blink-pull-request-open.png deleted file mode 100644 index 223144c2a..000000000 Binary files a/book/06-github/images/blink-pull-request-open.png and /dev/null differ diff --git a/book/06-github/images/emoji.png b/book/06-github/images/emoji.png deleted file mode 100644 index 42b01fb06..000000000 Binary files a/book/06-github/images/emoji.png and /dev/null differ diff --git a/book/06-github/images/hubot.png b/book/06-github/images/hubot.png deleted file mode 100644 index b057f1de2..000000000 Binary files a/book/06-github/images/hubot.png and /dev/null differ diff --git a/book/06-github/images/notifications.png b/book/06-github/images/notifications.png deleted file mode 100644 index 31e059517..000000000 Binary files a/book/06-github/images/notifications.png and /dev/null differ diff --git a/book/06-github/sections/1-setting-up-account.asc b/book/06-github/sections/1-setting-up-account.asc index 922efc5d5..56fc5c84e 100644 --- a/book/06-github/sections/1-setting-up-account.asc +++ b/book/06-github/sections/1-setting-up-account.asc @@ -9,12 +9,12 @@ image::images/signup.png[The GitHub sign-up form.] The next thing you'll see is the pricing page for upgraded plans, but it's safe to ignore this for now. GitHub will send you an email to verify the address you provided. -Go ahead and do this, it's pretty important (as we'll see later). +Go ahead and do this; it's pretty important (as we'll see later). [NOTE] ==== GitHub provides all of its functionality with free accounts, with the limitation that all of your projects are fully public (everyone has read access). -GitHub's paid plans include a set number of private projects, but we won't be covering those in this book. +GitHub's paid plans also include the option of creating private projects, but we won't be covering those in this book. ==== Clicking the Octocat logo at the top-left of the screen will take you to your dashboard page. @@ -27,7 +27,7 @@ As of right now, you're fully able to connect with Git repositories using the `h However, to simply clone public projects, you don't even need to sign up - the account we just created comes into play when we fork projects and push to our forks a bit later. If you'd like to use SSH remotes, you'll need to configure a public key. -(If you don't already have one, see <<_generate_ssh_key>>.) +(If you don't already have one, see <>.) Open up your account settings using the link at the top-right of the window: .The ``Account settings'' link. diff --git a/book/06-github/sections/2-contributing.asc b/book/06-github/sections/2-contributing.asc index 6847ece4c..edcc081a8 100644 --- a/book/06-github/sections/2-contributing.asc +++ b/book/06-github/sections/2-contributing.asc @@ -5,7 +5,7 @@ Now that our account is set up, let's walk through some details that could be us ==== Forking Projects (((forking))) -If you want to contribute to an existing project to which you don’t have push access, you can ``fork'' the project. +If you want to contribute to an existing project to which you don't have push access, you can ``fork'' the project. When you ``fork'' a project, GitHub will make a copy of the project that is entirely yours; it lives in your namespace, and you can push to it. [NOTE] @@ -14,7 +14,7 @@ Historically, the term ``fork'' has been somewhat negative in context, meaning t In GitHub, a ``fork'' is simply the same project in your own namespace, allowing you to make changes to a project publicly as a way to contribute in a more open manner. ==== -This way, projects don’t have to worry about adding users as collaborators to give them push access. +This way, projects don't have to worry about adding users as collaborators to give them push access. People can fork a project, push to it, and contribute their changes back to the original repository by creating what's called a Pull Request, which we'll cover next. This opens up a discussion thread with code review, and the owner and the contributor can then communicate about the change until the owner is happy with it, at which point the owner can merge it in. @@ -26,13 +26,13 @@ image::images/forkbutton.png[The ``Fork'' button.] After a few seconds, you'll be taken to your new project page, with your own writeable copy of the code. -[[_github_flow]] +[[ch06-github_flow]] ==== The GitHub Flow (((GitHub, Flow))) GitHub is designed around a particular collaboration workflow, centered on Pull Requests. This flow works whether you're collaborating with a tightly-knit team in a single shared repository, or a globally-distributed company or network of strangers contributing to a project through dozens of forks. -It is centered on the <<_topic_branch>> workflow covered in <<_git_branching>>. +It is centered on the <> workflow covered in <>. Here's how it generally works: @@ -43,8 +43,9 @@ Here's how it generally works: 5. Open a Pull Request on GitHub. 6. Discuss, and optionally continue committing. 7. The project owner merges or closes the Pull Request. +8. Sync the updated master back to your fork. -This is basically the Integration Manager workflow covered in <<_integration_manager>>, but instead of using email to communicate and review changes, teams use GitHub's web based tools. +This is basically the Integration Manager workflow covered in <>, but instead of using email to communicate and review changes, teams use GitHub's web based tools. Let's walk through an example of proposing a change to an open source project hosted on GitHub using this flow. @@ -55,7 +56,8 @@ Tony is looking for code to run on his Arduino programmable microcontroller and .The project we want to contribute to. image::images/blink-01-start.png[The project we want to contribute to.] -The only problem is that the blinking rate is too fast, we think it's much nicer to wait 3 seconds instead of 1 in between each state change. +The only problem is that the blinking rate is too fast. +We think it's much nicer to wait 3 seconds instead of 1 in between each state change. So let's improve the program and submit it back to the project as a proposed change. First, we click the 'Fork' button as mentioned earlier to get our own copy of the project. @@ -71,7 +73,9 @@ $ cd blink $ git checkout -b slow-blink <2> Switched to a new branch 'slow-blink' -$ sed -i '' 's/1000/3000/' blink.ino <3> +$ sed -i '' 's/1000/3000/' blink.ino (macOS) <3> +# If you're on a Linux system, do this instead: +# $ sed -i 's/1000/3000/' blink.ino <3> $ git diff --word-diff <4> diff --git a/blink.ino b/blink.ino @@ -110,7 +114,7 @@ To https://github.com/tonychacon/blink <5> Commit our change to the topic branch <6> Push our new topic branch back up to our GitHub fork -Now if we go back to our fork on GitHub, we can see that GitHub noticed that we pushed a new topic branch up and present us with a big green button to check out our changes and open a Pull Request to the original project. +Now if we go back to our fork on GitHub, we can see that GitHub noticed that we pushed a new topic branch up and presents us with a big green button to check out our changes and open a Pull Request to the original project. You can alternatively go to the ``Branches'' page at `https://github.com///branches` to locate your branch and open a new Pull Request from there. @@ -130,25 +134,31 @@ When you hit the 'Create pull request' button on this screen, the owner of the p [NOTE] ==== -Though Pull Requests are used commonly for public projects like this when the contributor has a complete change ready to be made, it's also often used in internal projects _at the beginning_ of the development cycle. Since you can keep pushing to the topic branch even *after* the Pull Request is opened, it's often opened early and used as a way to iterate on work as a team within a context, rather than opened at the very end of the process. +Though Pull Requests are used commonly for public projects like this when the contributor has a complete change ready to be made, it's also often used in internal projects _at the beginning_ of the development cycle. +Since you can keep pushing to the topic branch even *after* the Pull Request is opened, it's often opened early and used as a way to iterate on work as a team within a context, rather than opened at the very end of the process. ==== ===== Iterating on a Pull Request -At this point, the project owner can look at the suggested change and merge it, reject it or comment on it. Let's say that he likes the idea, but would prefer a slightly longer time for the light to be off than on. +At this point, the project owner can look at the suggested change and merge it, reject it or comment on it. +Let's say that he likes the idea, but would prefer a slightly longer time for the light to be off than on. -Where this conversation may take place over email in the workflows presented in <<_distributed_git>>, on GitHub this happens online. The project owner can review the unified diff and leave a comment by clicking on any of the lines. +Where this conversation may take place over email in the workflows presented in <>, on GitHub this happens online. +The project owner can review the unified diff and leave a comment by clicking on any of the lines. .Comment on a specific line of code in a Pull Request image::images/blink-04-pr-comment.png[PR line comment] -Once the maintainer makes this comment, the person who opened the Pull Request (and indeed, anyone else watching the repository) will get a notification. We'll go over customizing this later, but if he had email notifications turned on, Tony would get an email like this: +Once the maintainer makes this comment, the person who opened the Pull Request (and indeed, anyone else watching the repository) will get a notification. +We'll go over customizing this later, but if he had email notifications turned on, Tony would get an email like this: [[_email_notification]] .Comments sent as email notifications image::images/blink-04-email.png[Email notification] -Anyone can also leave general comments on the Pull Request. In <<_pr_discussion>> we can see an example of the project owner both commenting on a line of code and then leaving a general comment in the discussion section. You can see that the code comments are brought into the conversation as well. +Anyone can also leave general comments on the Pull Request. +In <<_pr_discussion>> we can see an example of the project owner both commenting on a line of code and then leaving a general comment in the discussion section. +You can see that the code comments are brought into the conversation as well. [[_pr_discussion]] .Pull Request discussion page @@ -165,18 +175,26 @@ Adding commits to an existing Pull Request doesn't trigger a notification, so on .Pull Request final image::images/blink-06-final.png[PR final] -An interesting thing to notice is that if you click on the ``Files Changed'' tab on this Pull Request, you'll get the ``unified'' diff -- that is, the total aggregate difference that would be introduced to your main branch if this topic branch was merged in. In `git diff` terms, it basically automatically shows you `git diff master...` for the branch this Pull Request is based on. See <<_what_is_introduced>> for more about this type of diff. +An interesting thing to notice is that if you click on the ``Files Changed'' tab on this Pull Request, you'll get the ``unified'' diff -- that is, the total aggregate difference that would be introduced to your main branch if this topic branch was merged in. +In `git diff` terms, it basically automatically shows you `git diff master...` for the branch this Pull Request is based on. +See <> for more about this type of diff. -The other thing you'll notice is that GitHub checks to see if the Pull Request merges cleanly and provides a button to do the merge for you on the server. This button only shows up if you have write access to the repository and a trivial merge is possible. If you click it GitHub will perform a ``non-fast-forward'' merge, meaning that even if the merge *could* be a fast-forward, it will still create a merge commit. +The other thing you'll notice is that GitHub checks to see if the Pull Request merges cleanly and provides a button to do the merge for you on the server. +This button only shows up if you have write access to the repository and a trivial merge is possible. +If you click it GitHub will perform a ``non-fast-forward'' merge, meaning that even if the merge *could* be a fast-forward, it will still create a merge commit. -If you would prefer, you can simply pull the branch down and merge it locally. If you merge this branch into the `master` branch and push it to GitHub, the Pull Request will automatically be closed. +If you would prefer, you can simply pull the branch down and merge it locally. +If you merge this branch into the `master` branch and push it to GitHub, the Pull Request will automatically be closed. -This is the basic workflow that most GitHub projects use. Topic branches are created, Pull Requests are opened on them, a discussion ensues, possibly more work is done on the branch and eventually the request is either closed or merged. +This is the basic workflow that most GitHub projects use. +Topic branches are created, Pull Requests are opened on them, a discussion ensues, possibly more work is done on the branch and eventually the request is either closed or merged. [NOTE] .Not Only Forks ==== -It's important to note that you can also open a Pull Request between two branches in the same repository. If you're working on a feature with someone and you both have write access to the project, you can push a topic branch to the repository and open a Pull Request on it to the `master` branch of that same project to initiate the code review and discussion process. No forking necessary. +It's important to note that you can also open a Pull Request between two branches in the same repository. +If you're working on a feature with someone and you both have write access to the project, you can push a topic branch to the repository and open a Pull Request on it to the `master` branch of that same project to initiate the code review and discussion process. +No forking necessary. ==== ==== Advanced Pull Requests @@ -185,15 +203,22 @@ Now that we've covered the basics of contributing to a project on GitHub, let's ===== Pull Requests as Patches -It's important to understand that many projects don't really think of Pull Requests as queues of perfect patches that should apply cleanly in order, as most mailing list-based projects think of patch series contributions. Most GitHub projects think about Pull Request branches as iterative conversations around a proposed change, culminating in a unified diff that is applied by merging. +It's important to understand that many projects don't really think of Pull Requests as queues of perfect patches that should apply cleanly in order, as most mailing list-based projects think of patch series contributions. +Most GitHub projects think about Pull Request branches as iterative conversations around a proposed change, culminating in a unified diff that is applied by merging. -This is an important distinction, because generally the change is suggested before the code is thought to be perfect, which is far more rare with mailing list based patch series contributions. This enables an earlier conversation with the maintainers so that arriving at the proper solution is more of a community effort. When code is proposed with a Pull Request and the maintainers or community suggest a change, the patch series is generally not re-rolled, but instead the difference is pushed as a new commit to the branch, moving the conversation forward with the context of the previous work intact. +This is an important distinction, because generally the change is suggested before the code is thought to be perfect, which is far more rare with mailing list based patch series contributions. +This enables an earlier conversation with the maintainers so that arriving at the proper solution is more of a community effort. +When code is proposed with a Pull Request and the maintainers or community suggest a change, the patch series is generally not re-rolled, but instead the difference is pushed as a new commit to the branch, moving the conversation forward with the context of the previous work intact. -For instance, if you go back and look again at <<_pr_final>>, you'll notice that the contributor did not rebase his commit and send another Pull Request. Instead they added new commits and pushed them to the existing branch. This way if you go back and look at this Pull Request in the future, you can easily find all of the context of why decisions were made. Pushing the ``Merge'' button on the site purposefully creates a merge commit that references the Pull Request so that it's easy to go back and research the original conversation if necessary. +For instance, if you go back and look again at <<_pr_final>>, you'll notice that the contributor did not rebase his commit and send another Pull Request. +Instead they added new commits and pushed them to the existing branch. +This way if you go back and look at this Pull Request in the future, you can easily find all of the context of why decisions were made. +Pushing the ``Merge'' button on the site purposefully creates a merge commit that references the Pull Request so that it's easy to go back and research the original conversation if necessary. ===== Keeping up with Upstream -If your Pull Request becomes out of date or otherwise doesn't merge cleanly, you will want to fix it so the maintainer can easily merge it. GitHub will test this for you and let you know at the bottom of every Pull Request if the merge is trivial or not. +If your Pull Request becomes out of date or otherwise doesn't merge cleanly, you will want to fix it so the maintainer can easily merge it. +GitHub will test this for you and let you know at the bottom of every Pull Request if the merge is trivial or not. [[_pr_fail]] .Pull Request does not merge cleanly @@ -201,13 +226,16 @@ image::images/pr-01-fail.png[PR merge failure] If you see something like <<_pr_fail>>, you'll want to fix your branch so that it turns green and the maintainer doesn't have to do extra work. -You have two main options in order to do this. You can either rebase your branch on top of whatever the target branch is (normally the `master` branch of the repository you forked), or you can merge the target branch into your branch. +You have two main options in order to do this. +You can either rebase your branch on top of whatever the target branch is (normally the `master` branch of the repository you forked), or you can merge the target branch into your branch. -Most developers on GitHub will choose to do the latter, for the same reasons we just went over in the previous section. What matters is the history and the final merge, so rebasing isn't getting you much other than a slightly cleaner history and in return is *far* more difficult and error prone. +Most developers on GitHub will choose to do the latter, for the same reasons we just went over in the previous section. +What matters is the history and the final merge, so rebasing isn't getting you much other than a slightly cleaner history and in return is *far* more difficult and error prone. If you want to merge in the target branch to make your Pull Request mergeable, you would add the original repository as a new remote, fetch from it, merge the main branch of that repository into your topic branch, fix any issues and finally push it back up to the same branch you opened the Pull Request on. -For example, let's say that in the ``tonychacon'' example we were using before, the original author made a change that would create a conflict in the Pull Request. Let's go through those steps. +For example, let's say that in the ``tonychacon'' example we were using before, the original author made a change that would create a conflict in the Pull Request. +Let's go through those steps. [source,console] ---- @@ -244,7 +272,7 @@ To https://github.com/tonychacon/blink <1> Add the original repository as a remote named ``upstream'' <2> Fetch the newest work from that remote -<3> Merge the main branch into your topic branch +<3> Merge the main branch of that repository into your topic branch <4> Fix the conflict that occurred <5> Push back up to the same topic branch @@ -254,17 +282,28 @@ Once you do that, the Pull Request will be automatically updated and re-checked .Pull Request now merges cleanly image::images/pr-02-merge-fix.png[PR fixed] -One of the great things about Git is that you can do that continuously. If you have a very long-running project, you can easily merge from the target branch over and over again and only have to deal with conflicts that have arisen since the last time that you merged, making the process very manageable. +One of the great things about Git is that you can do that continuously. +If you have a very long-running project, you can easily merge from the target branch over and over again and only have to deal with conflicts that have arisen since the last time that you merged, making the process very manageable. -If you absolutely wish to rebase the branch to clean it up, you can certainly do so, but it is highly encouraged to not force push over the branch that the Pull Request is already opened on. If other people have pulled it down and done more work on it, you run into all of the issues outlined in <<_rebase_peril>>. Instead, push the rebased branch to a new branch on GitHub and open a brand new Pull Request referencing the old one, then close the original. +If you absolutely wish to rebase the branch to clean it up, you can certainly do so, but it is highly encouraged to not force push over the branch that the Pull Request is already opened on. +If other people have pulled it down and done more work on it, you run into all of the issues outlined in <>. +Instead, push the rebased branch to a new branch on GitHub and open a brand new Pull Request referencing the old one, then close the original. ===== References -Your next question may be ``How do I reference the old Pull Request?''. It turns out there are many, many ways to reference other things almost anywhere you can write in GitHub. +Your next question may be ``How do I reference the old Pull Request?''. +It turns out there are many, many ways to reference other things almost anywhere you can write in GitHub. -Let's start with how to cross-reference another Pull Request or an Issue. All Pull Requests and Issues are assigned numbers and they are unique within the project. For example, you can't have Pull Request #3 _and_ Issue #3. If you want to reference any Pull Request or Issue from any other one, you can simply put `#` in any comment or description. You can also be more specific if the Issue or Pull request lives somewhere else; write `username#` if you're referring to an Issue or Pull Request in a fork of the repository you're in, or `username/repo#` to reference something in another repository. +Let's start with how to cross-reference another Pull Request or an Issue. +All Pull Requests and Issues are assigned numbers and they are unique within the project. +For example, you can't have Pull Request #3 _and_ Issue #3. +If you want to reference any Pull Request or Issue from any other one, you can simply put `#` in any comment or description. +You can also be more specific if the Issue or Pull request lives somewhere else; write `username#` if you're referring to an Issue or Pull Request in a fork of the repository you're in, or `username/repo#` to reference something in another repository. -Let's look at an example. Say we rebased the branch in the previous example, created a new pull request for it, and now we want to reference the old pull request from the new one. We also want to reference an issue in the fork of the repository and an issue in a completely different project. We can fill out the description just like <<_pr_references>>. +Let's look at an example. +Say we rebased the branch in the previous example, created a new pull request for it, and now we want to reference the old pull request from the new one. +We also want to reference an issue in the fork of the repository and an issue in a completely different project. +We can fill out the description just like <<_pr_references>>. [[_pr_references]] .Cross references in a Pull Request. @@ -278,17 +317,23 @@ image::images/mentions-02-render.png[PR references rendered] Notice that the full GitHub URL we put in there was shortened to just the information needed. -Now if Tony goes back and closes out the original Pull Request, we can see that by mentioning it in the new one, GitHub has automatically created a trackback event in the Pull Request timeline. This means that anyone who visits this Pull Request and sees that it is closed can easily link back to the one that superseded it. The link will look something like <<_pr_closed>>. +Now if Tony goes back and closes out the original Pull Request, we can see that by mentioning it in the new one, GitHub has automatically created a trackback event in the Pull Request timeline. +This means that anyone who visits this Pull Request and sees that it is closed can easily link back to the one that superseded it. +The link will look something like <<_pr_closed>>. [[_pr_closed]] -.Cross references rendered in a Pull Request. +.Link back to the new Pull Request in the closed Pull Request timeline. image::images/mentions-03-closed.png[PR closed] -In addition to issue numbers, you can also reference a specific commit by SHA-1. You have to specify a full 40 character SHA-1, but if GitHub sees that in a comment, it will link directly to the commit. Again, you can reference commits in forks or other repositories in the same way you did with issues. +In addition to issue numbers, you can also reference a specific commit by SHA-1. +You have to specify a full 40 character SHA-1, but if GitHub sees that in a comment, it will link directly to the commit. +Again, you can reference commits in forks or other repositories in the same way you did with issues. ==== GitHub Flavored Markdown -Linking to other Issues is just the beginning of interesting things you can do with almost any text box on GitHub. In Issue and Pull Request descriptions, comments, code comments and more, you can use what is called ``GitHub Flavored Markdown''. Markdown is like writing in plain text but which is rendered richly. +Linking to other Issues is just the beginning of interesting things you can do with almost any text box on GitHub. +In Issue and Pull Request descriptions, comments, code comments and more, you can use what is called ``GitHub Flavored Markdown''. +Markdown is like writing in plain text but which is rendered richly. See <<_example_markdown>> for an example of how comments or text can be written and then rendered using Markdown. @@ -296,11 +341,14 @@ See <<_example_markdown>> for an example of how comments or text can be written .An example of GitHub Flavored Markdown as written and as rendered. image::images/markdown-01-example.png[Example Markdown] -The GitHub flavor of Markdown adds more things you can do beyond the basic Markdown syntax. These can all be really useful when creating useful Pull Request or Issue comments or descriptions. +The GitHub flavor of Markdown adds more things you can do beyond the basic Markdown syntax. +These can all be really useful when creating useful Pull Request or Issue comments or descriptions. ===== Task Lists -The first really useful GitHub specific Markdown feature, especially for use in Pull Requests, is the Task List. A task list is a list of checkboxes of things you want to get done. Putting them into an Issue or Pull Request normally indicates things that you want to get done before you consider the item complete. +The first really useful GitHub specific Markdown feature, especially for use in Pull Requests, is the Task List. +A task list is a list of checkboxes of things you want to get done. +Putting them into an Issue or Pull Request normally indicates things that you want to get done before you consider the item complete. You can create a task list like this: @@ -311,15 +359,19 @@ You can create a task list like this: - [ ] Document the code ---- -If we include this in the description of our Pull Request or Issue, we'll see it rendered like <<_task_lists>> +If we include this in the description of our Pull Request or Issue, we'll see it rendered like <<_eg_task_lists>> -[[_task_lists]] +[[_eg_task_lists]] .Task lists rendered in a Markdown comment. image::images/markdown-02-tasks.png[Example Task List] -This is often used in Pull Requests to indicate what all you would like to get done on the branch before the Pull Request will be ready to merge. The really cool part is that you can simply click the checkboxes to update the comment -- you don't have to edit the Markdown directly to check tasks off. +This is often used in Pull Requests to indicate what all you would like to get done on the branch before the Pull Request will be ready to merge. +The really cool part is that you can simply click the checkboxes to update the comment -- you don't have to edit the Markdown directly to check tasks off. -What's more, GitHub will look for task lists in your Issues and Pull Requests and show them as metadata on the pages that list them out. For example, if you have a Pull Request with tasks and you look at the overview page of all Pull Requests, you can see how far done it is. This helps people break down Pull Requests into subtasks and helps other people track the progress of the branch. You can see an example of this in <<_task_list_progress>>. +What's more, GitHub will look for task lists in your Issues and Pull Requests and show them as metadata on the pages that list them out. +For example, if you have a Pull Request with tasks and you look at the overview page of all Pull Requests, you can see how far done it is. +This helps people break down Pull Requests into subtasks and helps other people track the progress of the branch. +You can see an example of this in <<_task_list_progress>>. [[_task_list_progress]] .Task list summary in the Pull Request list. @@ -329,7 +381,9 @@ These are incredibly useful when you open a Pull Request early and use it to tra ===== Code Snippets -You can also add code snippets to comments. This is especially useful if you want to present something that you _could_ try to do before actually implementing it as a commit on your branch. This is also often used to add example code of what is not working or what this Pull Request could implement. +You can also add code snippets to comments. +This is especially useful if you want to present something that you _could_ try to do before actually implementing it as a commit on your branch. +This is also often used to add example code of what is not working or what this Pull Request could implement. To add a snippet of code you have to ``fence'' it in backticks. @@ -343,7 +397,8 @@ for(int i=0 ; i < 5 ; i++) ``` ---- -If you add a language name like we did there with 'java', GitHub will also try to syntax highlight the snippet. In the case of the above example, it would end up rendering like <<_md_code>>. +If you add a language name like we did there with 'java', GitHub will also try to syntax highlight the snippet. +In the case of the above example, it would end up rendering like <<_md_code>>. [[_md_code]] .Rendered fenced code example. @@ -351,7 +406,9 @@ image::images/markdown-04-fenced-code.png[Rendered fenced code] ===== Quoting -If you're responding to a small part of a long comment, you can selectively quote out of the other comment by preceding the lines with the `>` character. In fact, this is so common and so useful that there is a keyboard shortcut for it. If you highlight text in a comment that you want to directly reply to and hit the `r` key, it will quote that text in the comment box for you. +If you're responding to a small part of a long comment, you can selectively quote out of the other comment by preceding the lines with the `>` character. +In fact, this is so common and so useful that there is a keyboard shortcut for it. +If you highlight text in a comment that you want to directly reply to and hit the `r` key, it will quote that text in the comment box for you. The quotes look something like this: @@ -371,13 +428,17 @@ image::images/markdown-05-quote.png[Rendered quoting] ===== Emoji -Finally, you can also use emoji in your comments. This is actually used quite extensively in comments you see on many GitHub Issues and Pull Requests. There is even an emoji helper in GitHub. If you are typing a comment and you start with a `:` character, an autocompleter will help you find what you're looking for. +Finally, you can also use emoji in your comments. +This is actually used quite extensively in comments you see on many GitHub Issues and Pull Requests. +There is even an emoji helper in GitHub. +If you are typing a comment and you start with a `:` character, an autocompleter will help you find what you're looking for. [[_md_emoji_auto]] .Emoji autocompleter in action. image::images/markdown-06-emoji-complete.png[Emoji autocompleter] -Emojis take the form of `::` anywhere in the comment. For instance, you could write something like this: +Emojis take the form of `::` anywhere in the comment. +For instance, you could write something like this: [source,text] ---- @@ -401,17 +462,80 @@ Not that this is incredibly useful, but it does add an element of fun and emotio [NOTE] ==== -There are actually quite a number of web services that make use of emoji characters these days. A great cheat sheet to reference to find emoji that expresses what you want to say can be found at: +There are actually quite a number of web services that make use of emoji characters these days. +A great cheat sheet to reference to find emoji that expresses what you want to say can be found at: -http://www.emoji-cheat-sheet.com +https://www.webfx.com/tools/emoji-cheat-sheet/ ==== ===== Images -This isn't technically GitHub Flavored Markdown, but it is incredibly useful. In addition to adding Markdown image links to comments, which can be difficult to find and embed URLs for, GitHub allows you to drag and drop images into text areas to embed them. +This isn't technically GitHub Flavored Markdown, but it is incredibly useful. +In addition to adding Markdown image links to comments, which can be difficult to find and embed URLs for, GitHub allows you to drag and drop images into text areas to embed them. [[_md_drag]] .Drag and drop images to upload them and auto-embed them. image::images/markdown-08-drag-drop.png[Drag and drop images] -If you look at <<_md_drag>>, you can see a small ``Parsed as Markdown'' hint above the text area. Clicking on that will give you a full cheat sheet of everything you can do with Markdown on GitHub. +If you look at <<_md_drag>>, you can see a small ``Parsed as Markdown'' hint above the text area. +Clicking on that will give you a full cheat sheet of everything you can do with Markdown on GitHub. + +[[_fetch_and_push_on_different_repositories]] +==== Keep your GitHub public repository up-to-date + +Once you've forked a GitHub repository, your repository (your "fork") exists independently from the original. +In particular, when the original repository has new commits, GitHub informs you by a message like: + +[source,text] +---- +This branch is 5 commits behind progit:master. +---- + +But your GitHub repository will never be automatically updated by GitHub; this is something that you must do yourself. +Fortunately, this is very easy to do. + +One possibility to do this requires no configuration. +For example, if you forked from `https://github.com/progit/progit2.git`, you can keep your `master` branch up-to-date like this: + +[source,console] +---- +$ git checkout master <1> +$ git pull https://github.com/progit/progit2.git <2> +$ git push origin master <3> +---- + +<1> If you were on another branch, return to `master`. +<2> Fetch changes from `https://github.com/progit/progit2.git` and merge them into `master`. +<3> Push your `master` branch to `origin`. + +This works, but it is a little tedious having to spell out the fetch URL every time. +You can automate this work with a bit of configuration: + +[source,console] +---- +$ git remote add progit https://github.com/progit/progit2.git <1> +$ git branch --set-upstream-to=progit/master master <2> +$ git config --local remote.pushDefault origin <3> +---- + +<1> Add the source repository and give it a name. + Here, I have chosen to call it `progit`. +<2> Set your `master` branch to fetch from the `progit` remote. +<3> Define the default push repository to `origin`. + +Once this is done, the workflow becomes much simpler: + +[source,console] +---- +$ git checkout master <1> +$ git pull <2> +$ git push <3> +---- + +<1> If you were on another branch, return to `master`. +<2> Fetch changes from `progit` and merge changes into `master`. +<3> Push your `master` branch to `origin`. + +This approach can be useful, but it's not without downsides. +Git will happily do this work for you silently, but it won't warn you if you make a commit to `master`, pull from `progit`, then push to `origin` -- all of those operations are valid with this setup. +So you'll have to take care never to commit directly to `master`, since that branch effectively belongs to the upstream repository. diff --git a/book/06-github/sections/3-maintaining.asc b/book/06-github/sections/3-maintaining.asc index 5612f874a..f174e15e9 100644 --- a/book/06-github/sections/3-maintaining.asc +++ b/book/06-github/sections/3-maintaining.asc @@ -24,7 +24,7 @@ All you really have to do here is provide a project name; the rest of the fields For now, just click the ``Create Repository'' button, and boom – you have a new repository on GitHub, named `/`. Since you have no code there yet, GitHub will show you instructions for how to create a brand-new Git repository, or connect an existing Git project. -We won't belabor this here; if you need a refresher, check out <<_git_basics_chapter>>. +We won't belabor this here; if you need a refresher, check out <>. Now that your project is hosted on GitHub, you can give the URL to anyone you want to share your project with. Every project on GitHub is accessible over HTTPS as `https://github.com//`, and over SSH as `git@github.com:/`. @@ -81,7 +81,7 @@ It gives you a link to the Pull Request on GitHub. It also gives you a few URLs that you can use from the command line. If you notice the line that says `git pull patch-1`, this is a simple way to merge in a remote branch without having to add a remote. -We went over this quickly in <<_checking_out_remotes>>. +We went over this quickly in <>. If you wish, you can create and switch to a topic branch and then run this command to merge in the Pull Request changes. The other interesting URLs are the `.diff` and `.patch` URLs, which as you may guess, provide unified diff and patch versions of the Pull Request. @@ -89,12 +89,12 @@ You could technically merge in the Pull Request work with something like this: [source,console] ---- -$ curl http://github.com/tonychacon/fade/pull/1.patch | git am +$ curl https://github.com/tonychacon/fade/pull/1.patch | git am ---- ===== Collaborating on the Pull Request -As we covered in <<_github_flow>>, you can now have a conversation with the person who opened the Pull Request. +As we covered in <>, you can now have a conversation with the person who opened the Pull Request. You can comment on specific lines of code, comment on whole commits or comment on the entire Pull Request itself, using GitHub Flavored Markdown everywhere. Every time someone else comments on the Pull Request you will continue to get email notifications so you know there is activity happening. @@ -120,12 +120,12 @@ If you decide you don't want to merge it, you can also just close the Pull Reque ===== Pull Request Refs If you're dealing with a *lot* of Pull Requests and don't want to add a bunch of remotes or do one time pulls every time, there is a neat trick that GitHub allows you to do. -This is a bit of an advanced trick and we'll go over the details of this a bit more in <<_refspec>>, but it can be pretty useful. +This is a bit of an advanced trick and we'll go over the details of this a bit more in <>, but it can be pretty useful. GitHub actually advertises the Pull Request branches for a repository as sort of pseudo-branches on the server. By default you don't get them when you clone, but they are there in an obscured way and you can access them pretty easily. -To demonstrate this, we're going to use a low-level command (often referred to as a ``plumbing'' command, which we'll read about more in <<_plumbing_porcelain>>) called `ls-remote`. +To demonstrate this, we're going to use a low-level command (often referred to as a ``plumbing'' command, which we'll read about more in <>) called `ls-remote`. This command is generally not used in day-to-day Git operations but it's useful to show us what references are present on the server. If we run this command against the ``blink'' repository we were using earlier, we will get a list of all the branches and tags and other references in the repository. diff --git a/book/06-github/sections/4-managing-organization.asc b/book/06-github/sections/4-managing-organization.asc index ea2119081..f3137e5dc 100644 --- a/book/06-github/sections/4-managing-organization.asc +++ b/book/06-github/sections/4-managing-organization.asc @@ -1,4 +1,4 @@ -[[_github_orgs]] +[[ch06-github_orgs]] === Managing an organization (((GitHub, organizations))) @@ -65,7 +65,7 @@ Special-interest teams like `ux`, `css`, or `refactoring` are useful for certain Organizations also give owners access to all the information about what went on under the organization. You can go to the 'Audit Log' tab and see what events have happened at an organization level, who did them and where in the world they were done. -[[_audit_log]] +[[_the_audit_log]] .The Audit log. image::images/orgs-03-audit.png[] diff --git a/book/06-github/sections/5-scripting.asc b/book/06-github/sections/5-scripting.asc index 6bfb16e77..b85917d73 100644 --- a/book/06-github/sections/5-scripting.asc +++ b/book/06-github/sections/5-scripting.asc @@ -159,7 +159,7 @@ $ curl https://api.github.com/gitignore/templates/Java *.war *.ear -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +# virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* " } @@ -296,7 +296,7 @@ This is really useful if you're using this API for test results so you don't acc Though we've been doing nearly everything through `curl` and simple HTTP requests in these examples, several open-source libraries exist that make this API available in a more idiomatic way. At the time of this writing, the supported languages include Go, Objective-C, Ruby, and .NET. -Check out http://github.com/octokit[] for more information on these, as they handle much of the HTTP for you. +Check out https://github.com/octokit[] for more information on these, as they handle much of the HTTP for you. Hopefully these tools can help you customize and modify GitHub to work better for your specific workflows. For complete documentation on the entire API as well as guides for common tasks, check out https://developer.github.com[]. diff --git a/book/07-git-tools/1-git-tools.asc b/book/07-git-tools/1-git-tools.asc deleted file mode 100644 index 073eae5fd..000000000 --- a/book/07-git-tools/1-git-tools.asc +++ /dev/null @@ -1,42 +0,0 @@ -[[_git_tools]] -== Git Tools - -By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. -You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. - -Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. - -include::sections/revision-selection.asc[] - -include::sections/interactive-staging.asc[] - -include::sections/stashing-cleaning.asc[] - -include::sections/signing.asc[] - -include::sections/searching.asc[] - -include::sections/rewriting-history.asc[] - -include::sections/reset.asc[] - -include::sections/advanced-merging.asc[] - -include::sections/rerere.asc[] - -include::sections/debugging.asc[] - -include::sections/submodules.asc[] - -include::sections/bundling.asc[] - -include::sections/replace.asc[] - -include::sections/credentials.asc[] - -=== Summary - -You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. -When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. -If you want to use subprojects in your project, you’ve learned how to accommodate those needs. -At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. diff --git a/book/07-git-tools/images/double-dot.png b/book/07-git-tools/images/double-dot.png deleted file mode 100644 index 53175c15d..000000000 Binary files a/book/07-git-tools/images/double-dot.png and /dev/null differ diff --git a/book/07-git-tools/images/replace1.png b/book/07-git-tools/images/replace1.png deleted file mode 100644 index f5a23f7fc..000000000 Binary files a/book/07-git-tools/images/replace1.png and /dev/null differ diff --git a/book/07-git-tools/images/replace2.png b/book/07-git-tools/images/replace2.png deleted file mode 100644 index 5b03076c8..000000000 Binary files a/book/07-git-tools/images/replace2.png and /dev/null differ diff --git a/book/07-git-tools/images/replace3.png b/book/07-git-tools/images/replace3.png deleted file mode 100644 index 5c3191cd9..000000000 Binary files a/book/07-git-tools/images/replace3.png and /dev/null differ diff --git a/book/07-git-tools/images/replace4.png b/book/07-git-tools/images/replace4.png deleted file mode 100644 index 553820c0a..000000000 Binary files a/book/07-git-tools/images/replace4.png and /dev/null differ diff --git a/book/07-git-tools/images/replace5.png b/book/07-git-tools/images/replace5.png deleted file mode 100644 index 41e7cd7bd..000000000 Binary files a/book/07-git-tools/images/replace5.png and /dev/null differ diff --git a/book/07-git-tools/images/rerere1.png b/book/07-git-tools/images/rerere1.png deleted file mode 100644 index 34ab3b7b7..000000000 Binary files a/book/07-git-tools/images/rerere1.png and /dev/null differ diff --git a/book/07-git-tools/images/rerere2.png b/book/07-git-tools/images/rerere2.png deleted file mode 100644 index 85dd47f4b..000000000 Binary files a/book/07-git-tools/images/rerere2.png and /dev/null differ diff --git a/book/07-git-tools/images/rerere3.png b/book/07-git-tools/images/rerere3.png deleted file mode 100644 index b299ac74c..000000000 Binary files a/book/07-git-tools/images/rerere3.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-checkout.png b/book/07-git-tools/images/reset-checkout.png deleted file mode 100644 index fe036345e..000000000 Binary files a/book/07-git-tools/images/reset-checkout.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-ex1.png b/book/07-git-tools/images/reset-ex1.png deleted file mode 100644 index 2ffd68b25..000000000 Binary files a/book/07-git-tools/images/reset-ex1.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-ex2.png b/book/07-git-tools/images/reset-ex2.png deleted file mode 100644 index f4ffd2a7a..000000000 Binary files a/book/07-git-tools/images/reset-ex2.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-ex3.png b/book/07-git-tools/images/reset-ex3.png deleted file mode 100644 index 742749332..000000000 Binary files a/book/07-git-tools/images/reset-ex3.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-ex4.png b/book/07-git-tools/images/reset-ex4.png deleted file mode 100644 index 3cfbf7fc7..000000000 Binary files a/book/07-git-tools/images/reset-ex4.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-ex5.png b/book/07-git-tools/images/reset-ex5.png deleted file mode 100644 index c21a2534b..000000000 Binary files a/book/07-git-tools/images/reset-ex5.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-ex6.png b/book/07-git-tools/images/reset-ex6.png deleted file mode 100644 index c64cc38f3..000000000 Binary files a/book/07-git-tools/images/reset-ex6.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-hard.png b/book/07-git-tools/images/reset-hard.png deleted file mode 100644 index a9da7cedc..000000000 Binary files a/book/07-git-tools/images/reset-hard.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-mixed.png b/book/07-git-tools/images/reset-mixed.png deleted file mode 100644 index 0266fe511..000000000 Binary files a/book/07-git-tools/images/reset-mixed.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-path1.png b/book/07-git-tools/images/reset-path1.png deleted file mode 100644 index 1672e02bd..000000000 Binary files a/book/07-git-tools/images/reset-path1.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-path2.png b/book/07-git-tools/images/reset-path2.png deleted file mode 100644 index 08308e5e6..000000000 Binary files a/book/07-git-tools/images/reset-path2.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-path3.png b/book/07-git-tools/images/reset-path3.png deleted file mode 100644 index e01f80aeb..000000000 Binary files a/book/07-git-tools/images/reset-path3.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-soft.png b/book/07-git-tools/images/reset-soft.png deleted file mode 100644 index 831d9f6f5..000000000 Binary files a/book/07-git-tools/images/reset-soft.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-squash-r1.png b/book/07-git-tools/images/reset-squash-r1.png deleted file mode 100644 index e703a3097..000000000 Binary files a/book/07-git-tools/images/reset-squash-r1.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-squash-r2.png b/book/07-git-tools/images/reset-squash-r2.png deleted file mode 100644 index 8b3bd4439..000000000 Binary files a/book/07-git-tools/images/reset-squash-r2.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-squash-r3.png b/book/07-git-tools/images/reset-squash-r3.png deleted file mode 100644 index 87e44cbed..000000000 Binary files a/book/07-git-tools/images/reset-squash-r3.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-start.png b/book/07-git-tools/images/reset-start.png deleted file mode 100644 index 70b3fb064..000000000 Binary files a/book/07-git-tools/images/reset-start.png and /dev/null differ diff --git a/book/07-git-tools/images/reset-workflow.png b/book/07-git-tools/images/reset-workflow.png deleted file mode 100644 index 1c01e0d55..000000000 Binary files a/book/07-git-tools/images/reset-workflow.png and /dev/null differ diff --git a/book/07-git-tools/images/undomerge-reset.png b/book/07-git-tools/images/undomerge-reset.png deleted file mode 100644 index 3ffcc6244..000000000 Binary files a/book/07-git-tools/images/undomerge-reset.png and /dev/null differ diff --git a/book/07-git-tools/images/undomerge-revert.png b/book/07-git-tools/images/undomerge-revert.png deleted file mode 100644 index 87cd7c93d..000000000 Binary files a/book/07-git-tools/images/undomerge-revert.png and /dev/null differ diff --git a/book/07-git-tools/images/undomerge-revert2.png b/book/07-git-tools/images/undomerge-revert2.png deleted file mode 100644 index dc5727eab..000000000 Binary files a/book/07-git-tools/images/undomerge-revert2.png and /dev/null differ diff --git a/book/07-git-tools/images/undomerge-revert3.png b/book/07-git-tools/images/undomerge-revert3.png deleted file mode 100644 index 71f94a63f..000000000 Binary files a/book/07-git-tools/images/undomerge-revert3.png and /dev/null differ diff --git a/book/07-git-tools/images/undomerge-start.png b/book/07-git-tools/images/undomerge-start.png deleted file mode 100644 index 518a71d88..000000000 Binary files a/book/07-git-tools/images/undomerge-start.png and /dev/null differ diff --git a/book/07-git-tools/sections/advanced-merging.asc b/book/07-git-tools/sections/advanced-merging.asc index 1c3767179..d8b7e9d95 100644 --- a/book/07-git-tools/sections/advanced-merging.asc +++ b/book/07-git-tools/sections/advanced-merging.asc @@ -14,12 +14,12 @@ We'll also cover some of the different, non-standard types of merges you can do, ==== Merge Conflicts -While we covered some basics on resolving merge conflicts in <<_basic_merge_conflicts>>, for more complex conflicts, Git provides a few tools to help you figure out what's going on and how to better deal with the conflict. +While we covered some basics on resolving merge conflicts in <>, for more complex conflicts, Git provides a few tools to help you figure out what's going on and how to better deal with the conflict. First of all, if at all possible, try to make sure your working directory is clean before doing a merge that may have conflicts. If you have work in progress, either commit it to a temporary branch or stash it. This makes it so that you can undo *anything* you try here. -If you have unsaved changes in your working directory when you try a merge, some of these tips may help you lose that work. +If you have unsaved changes in your working directory when you try a merge, some of these tips may help you preserve that work. Let's walk through a very simple example. We have a super simple Ruby file that prints 'hello world'. @@ -357,7 +357,7 @@ Let's explore a couple of tools that you now have at your disposal to determine Perhaps it's not obvious how exactly you should fix this conflict. You need more context. -One helpful tool is `git checkout` with the `--conflict' option. +One helpful tool is `git checkout` with the `--conflict` option. This will re-checkout the file again and replace the merge conflict markers. This can be useful if you want to reset the markers and try to resolve them again. @@ -406,7 +406,7 @@ Another useful tool when resolving merge conflicts is `git log`. This can help you get context on what may have contributed to the conflicts. Reviewing a little bit of history to remember why two lines of development were touching the same area of code can be really helpful sometimes. -To get a full list of all of the unique commits that were included in either branch involved in this merge, we can use the ``triple dot'' syntax that we learned in <<_triple_dot>>. +To get a full list of all of the unique commits that were included in either branch involved in this merge, we can use the ``triple dot'' syntax that we learned in <>. [source,console] ---- @@ -547,7 +547,7 @@ In most cases, if you follow the errant `git merge` with `git reset --hard HEAD~ .History after `git reset --hard HEAD~` image::images/undomerge-reset.png[History after `git reset --hard HEAD~`.] -We covered `reset` back in <<_git_reset>>, so it shouldn't be too hard to figure out what's going on here. +We covered `reset` back in <>, so it shouldn't be too hard to figure out what's going on here. Here's a quick refresher: `reset --hard` usually goes through three steps: . Move the branch HEAD points to. @@ -556,7 +556,7 @@ Here's a quick refresher: `reset --hard` usually goes through three steps: . Make the working directory look like the index. The downside of this approach is that it's rewriting history, which can be problematic with a shared repository. -Check out <<_rebase_peril>> for more on what can happen; the short version is that if other people have the commits you're rewriting, you should probably avoid `reset`. +Check out <> for more on what can happen; the short version is that if other people have the commits you're rewriting, you should probably avoid `reset`. This approach also won't work if any other commits have been created since the merge; moving the refs would effectively lose those changes. [[_reverse_commit]] diff --git a/book/07-git-tools/sections/bundling.asc b/book/07-git-tools/sections/bundling.asc index 489f455f0..85dbf8235 100644 --- a/book/07-git-tools/sections/bundling.asc +++ b/book/07-git-tools/sections/bundling.asc @@ -83,7 +83,7 @@ Unlike the network protocols which figure out the minimum set of data to transfe Now, you could just do the same thing and bundle the entire repository, which will work, but it's better to just bundle up the difference - just the three commits we just made locally. In order to do that, you'll have to calculate the difference. -As we described in <<_commit_ranges>>, you can specify a range of commits in a number of ways. +As we described in <>, you can specify a range of commits in a number of ways. To get the three commits that we have in our master branch that weren't in the branch we originally cloned, we can use something like `origin/master..master` or `master ^origin/master`. You can test that with the `log` command. diff --git a/book/07-git-tools/sections/credentials.asc b/book/07-git-tools/sections/credentials.asc index 4628bf8aa..7ff7826a9 100644 --- a/book/07-git-tools/sections/credentials.asc +++ b/book/07-git-tools/sections/credentials.asc @@ -19,8 +19,9 @@ Git has a few options provided in the box: The downside of this approach is that your passwords are stored in cleartext in a plain file in your home directory. * If you're using a Mac, Git comes with an ``osxkeychain'' mode, which caches credentials in the secure keychain that's attached to your system account. This method stores the credentials on disk, and they never expire, but they're encrypted with the same system that stores HTTPS certificates and Safari auto-fills. -* If you're using Windows, you can install a helper called ``wincred.'' +* If you're using Windows, you can install a helper called ``Git Credential Manager for Windows.'' This is similar to the ``osxkeychain'' helper described above, but uses the Windows Credential Store to control sensitive information. + It can be found at https://github.com/Microsoft/Git-Credential-Manager-for-Windows[]. You can choose one of these methods by setting a Git configuration value: @@ -167,7 +168,8 @@ Here's the full source code of our new credential helper: include::../git-credential-read-only[] -------- -<1> Here we parse the command-line options, allowing the user to specify the input file. The default is `~/.git-credentials`. +<1> Here we parse the command-line options, allowing the user to specify the input file. + The default is `~/.git-credentials`. <2> This program only responds if the action is `get` and the backing-store file exists. <3> This loop reads from stdin until the first blank line is reached. The inputs are stored in the `known` hash for later reference. diff --git a/book/07-git-tools/sections/debugging.asc b/book/07-git-tools/sections/debugging.asc index bf65ddf8f..018b50541 100644 --- a/book/07-git-tools/sections/debugging.asc +++ b/book/07-git-tools/sections/debugging.asc @@ -1,43 +1,46 @@ === Debugging with Git -Git also provides a couple of tools to help you debug issues in your projects. -Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. +In addition to being primarily for version control, Git also provides a couple commands to help you debug your source code projects. +Because Git is designed to handle nearly any type of content, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. [[_file_annotation]] ==== File Annotation If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. -So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. -This example uses the `-L` option to limit the output to lines 12 through 22: +So if you see that a method in your code is buggy, you can annotate the file with `git blame` to determine which commit was responsible for the introduction of that line. + +The following example uses `git blame` to determine which commit and committer was responsible for lines in the top-level Linux kernel `Makefile` and, further, uses the `-L` option to restrict the output of the annotation to lines 69 through 82 of that file: [source,console] ---- -$ git blame -L 12,22 simplegit.rb -^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master') -^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 13) command("git show #{tree}") -^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 14) end -^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 15) -9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 16) def log(tree = 'master') -79eaf55d (Scott Chacon 2008-04-06 10:15:08 -0700 17) command("git log #{tree}") -9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 18) end -9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 19) -42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20) def blame(path) -42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21) command("git blame #{path}") -42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end +$ git blame -L 69,82 Makefile +b8b0618cf6fab (Cheng Renquan 2009-05-26 16:03:07 +0800 69) ifeq ("$(origin V)", "command line") +b8b0618cf6fab (Cheng Renquan 2009-05-26 16:03:07 +0800 70) KBUILD_VERBOSE = $(V) +^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) endif +^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) ifndef KBUILD_VERBOSE +^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) KBUILD_VERBOSE = 0 +^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) endif +^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75) +066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 76) ifeq ($(KBUILD_VERBOSE),1) +066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 77) quiet = +066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 78) Q = +066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 79) else +066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 80) quiet=quiet_ +066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 81) Q = @ +066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 82) endif ---- Notice that the first field is the partial SHA-1 of the commit that last modified that line. -The next two fields are values extracted from that commit–the author name and the authored date of that commit – so you can easily see who modified that line and when. +The next two fields are values extracted from that commit -- the author name and the authored date of that commit -- so you can easily see who modified that line and when. After that come the line number and the content of the file. -Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. -That commit is when this file was first added to this project, and those lines have been unchanged since. -This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA-1, but that is what it means here. +Also note the `^1da177e4c3f4` commit lines, where the `^` prefix designates lines that were introduced in the repository's initial commit and have remained unchanged ever since. +This is a tad confusing, because now you've seen at least three different ways that Git uses the `^` to modify a commit SHA-1, but that is what it means here. -Another cool thing about Git is that it doesn’t track file renames explicitly. +Another cool thing about Git is that it doesn't track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. -If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. +If you pass `-C` to `git blame`, Git analyzes the file you're annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. For example, say you are refactoring a file named `GITServerHandler.m` into multiple files, one of which is `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, you can see where sections of the code originally came from: @@ -67,14 +70,14 @@ Git tells you the original commit where you wrote those lines, even if it was in ==== Binary Search Annotating a file helps if you know where the issue is to begin with. -If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. +If you don't know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you'll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. -Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. -You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. -You can bisect the code to find out. -First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. -Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: +Let's say you just pushed out a release of your code to a production environment, you're getting bug reports about something that wasn't happening in your development environment, and you can't imagine why the code is doing that. +You go back to your code, and it turns out you can reproduce the issue, but you can't figure out what is going wrong. +You can _bisect_ the code to find out. +First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you're on is broken. +Then, you must tell bisect when the last known good state was, using `git bisect good `: [source,console] ---- @@ -87,7 +90,7 @@ Bisecting: 6 revisions left to test after this Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. -If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. +If it does, then it was introduced sometime before this middle commit; if it doesn't, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: [source,console] @@ -97,7 +100,7 @@ Bisecting: 3 revisions left to test after this [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing ---- -Now you’re on another commit, halfway between the one you just tested and your bad commit. +Now you're on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: [source,console] @@ -124,7 +127,7 @@ Date: Tue Jan 27 14:48:32 2009 -0800 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config ---- -When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: +When you're finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you'll end up in a weird state: [source,console] ---- diff --git a/book/07-git-tools/sections/interactive-staging.asc b/book/07-git-tools/sections/interactive-staging.asc index d448ebc53..affa704b2 100644 --- a/book/07-git-tools/sections/interactive-staging.asc +++ b/book/07-git-tools/sections/interactive-staging.asc @@ -1,11 +1,11 @@ [[_interactive_staging]] === Interactive Staging -Git comes with a couple of scripts that make some command-line tasks easier. -Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. -These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. -This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. -If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: +In this section, you'll look at a few interactive Git commands that can help you craft your commits to include only certain combinations and parts of files. +These tools are helpful if you modify a number of files extensively, then decide that you want those changes to be partitioned into several focused commits rather than one big messy commit. +This way, you can make sure your commits are logically separate changesets and can be reviewed easily by the developers working with you. + +If you run `git add` with the `-i` or `--interactive` option, Git enters an interactive shell mode, displaying something like this: [source,console] ---- @@ -16,24 +16,23 @@ $ git add -i 3: unchanged +5/-1 lib/simplegit.rb *** Commands *** - 1: status 2: update 3: revert 4: add untracked - 5: patch 6: diff 7: quit 8: help + 1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked + 5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp What now> ---- -You can see that this command shows you a much different view of your staging area – basically the same information you get with `git status` but a bit more succinct and informative. -It lists the changes you’ve staged on the left and unstaged changes on the right. +You can see that this command shows you a much different view of your staging area than you're probably used to -- basically, the same information you get with `git status` but a bit more succinct and informative. +It lists the changes you've staged on the left and unstaged changes on the right. -After this comes a Commands section. -Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. +After this comes a ``Commands'' section, which allows you to do a number of things like staging and unstaging files, staging parts of files, adding untracked files, and displaying diffs of what has been staged. ==== Staging and Unstaging Files -If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: +If you type `u` or `2` (for update) at the `What now>` prompt, you're prompted for which files you want to stage: [source,console] ---- -What now> 2 +What now> u staged unstaged path 1: unchanged +0/-1 TODO 2: unchanged +1/-1 index.html @@ -41,7 +40,7 @@ What now> 2 Update>> ---- -To stage the TODO and index.html files, you can type the numbers: +To stage the `TODO` and `index.html` files, you can type the numbers: [source,console] ---- @@ -62,24 +61,24 @@ Update>> updated 2 paths *** Commands *** - 1: status 2: update 3: revert 4: add untracked - 5: patch 6: diff 7: quit 8: help -What now> 1 + 1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked + 5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp +What now> s staged unstaged path 1: +0/-1 nothing TODO 2: +1/-1 nothing index.html 3: unchanged +5/-1 lib/simplegit.rb ---- -Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. -If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: +Now you can see that the `TODO` and `index.html` files are staged and the `simplegit.rb` file is still unstaged. +If you want to unstage the `TODO` file at this point, you use the `r` or `3` (for revert) option: [source,console] ---- *** Commands *** - 1: status 2: update 3: revert 4: add untracked - 5: patch 6: diff 7: quit 8: help -What now> 3 + 1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked + 5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp +What now> r staged unstaged path 1: +0/-1 nothing TODO 2: +1/-1 nothing index.html @@ -93,30 +92,30 @@ Revert>> [enter] reverted one path ---- -Looking at your Git status again, you can see that you’ve unstaged the TODO file: +Looking at your Git status again, you can see that you've unstaged the `TODO` file: [source,console] ---- *** Commands *** - 1: status 2: update 3: revert 4: add untracked - 5: patch 6: diff 7: quit 8: help -What now> 1 + 1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked + 5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp +What now> s staged unstaged path 1: unchanged +0/-1 TODO 2: +1/-1 nothing index.html 3: unchanged +5/-1 lib/simplegit.rb ---- -To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. +To see the diff of what you've staged, you can use the `d` or `6` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: [source,console] ---- *** Commands *** - 1: status 2: update 3: revert 4: add untracked - 5: patch 6: diff 7: quit 8: help -What now> 6 + 1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked + 5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp +What now> d staged unstaged path 1: +1/-1 nothing index.html Review diff>> 1 @@ -138,9 +137,9 @@ With these basic commands, you can use the interactive add mode to deal with you ==== Staging Patches -It’s also possible for Git to stage certain parts of files and not the rest. -For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. -From the interactive prompt, type `5` or `p` (for patch). +It's also possible for Git to stage certain _parts_ of files and not the rest. +For example, if you make two changes to your `simplegit.rb` file and want to stage one of them and not the other, doing so is very easy in Git. +From the same interactive prompt explained in the previous section, type `p` or `5` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one: [source,console] @@ -182,7 +181,7 @@ e - manually edit the current hunk ? - print help ---- -Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. +Generally, you'll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this: [source,console] @@ -194,12 +193,12 @@ What now> 1 3: +1/-1 +4/-0 lib/simplegit.rb ---- -The status of the simplegit.rb file is interesting. +The status of the `simplegit.rb` file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. -You’ve partially staged this file. +You've partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files. -You also don’t need to be in interactive add mode to do the partial-file staging – you can start the same script by using `git add -p` or `git add --patch` on the command line. +You also don't need to be in interactive add mode to do the partial-file staging -- you can start the same script by using `git add -p` or `git add --patch` on the command line. -Furthermore, you can use patch mode for partially resetting files with the `reset --patch` command, for checking out parts of files with the `checkout --patch` command and for stashing parts of files with the `stash save --patch` command. +Furthermore, you can use patch mode for partially resetting files with the `git reset --patch` command, for checking out parts of files with the `git checkout --patch` command and for stashing parts of files with the `git stash save --patch` command. We'll go into more details on each of these as we get to more advanced usages of these commands. diff --git a/book/07-git-tools/sections/replace.asc b/book/07-git-tools/sections/replace.asc index 7e504bfd7..95cf842a2 100644 --- a/book/07-git-tools/sections/replace.asc +++ b/book/07-git-tools/sections/replace.asc @@ -1,13 +1,13 @@ [[_replace]] === Replace -Git's objects are unchangeable, but it does provide an interesting way to pretend to replace objects in its database with other objects. +As we've emphasized before, the objects in Git's object database are unchangeable, but Git does provide an interesting way to _pretend_ to replace objects in its database with other objects. -The `replace` command lets you specify an object in Git and say "every time you see this, pretend it's this other thing". -This is most commonly useful for replacing one commit in your history with another one. +The `replace` command lets you specify an object in Git and say "every time you refer to _this_ object, pretend it's a _different_ object". +This is most commonly useful for replacing one commit in your history with another one without having to rebuild the entire history with, say, `git filter-branch`. For example, let's say you have a huge code history and want to split your repository into one short history for new developers and one much longer and larger history for people interested in data mining. -You can graft one history onto the other by `replace`ing the earliest commit in the new line with the latest commit on the older one. +You can graft one history onto the other by "replacing" the earliest commit in the new line with the latest commit on the older one. This is nice because it means that you don't actually have to rewrite every commit in the new history, as you would normally have to do to join them together (because the parentage affects the SHA-1s). Let's try this out. @@ -94,7 +94,7 @@ $ echo 'get history from blah blah blah' | git commit-tree 9c68fdc^{tree} The `commit-tree` command is one of a set of commands that are commonly referred to as 'plumbing' commands. These are commands that are not generally meant to be used directly, but instead are used by *other* Git commands to do smaller jobs. On occasions when we're doing weirder things like this, they allow us to do really low-level things but are not meant for daily use. -You can read more about plumbing commands in <<_plumbing_porcelain>> +You can read more about plumbing commands in <> ===== image::images/replace3.png[] diff --git a/book/07-git-tools/sections/rerere.asc b/book/07-git-tools/sections/rerere.asc index 6db821513..a030104c3 100644 --- a/book/07-git-tools/sections/rerere.asc +++ b/book/07-git-tools/sections/rerere.asc @@ -1,28 +1,28 @@ -[[_rerere]] +[[ref_rerere]] === Rerere The `git rerere` functionality is a bit of a hidden feature. -The name stands for ``reuse recorded resolution'' and as the name implies, it allows you to ask Git to remember how you've resolved a hunk conflict so that the next time it sees the same conflict, Git can automatically resolve it for you. +The name stands for ``reuse recorded resolution'' and, as the name implies, it allows you to ask Git to remember how you've resolved a hunk conflict so that the next time it sees the same conflict, Git can resolve it for you automatically. There are a number of scenarios in which this functionality might be really handy. -One of the examples that is mentioned in the documentation is if you want to make sure a long lived topic branch will merge cleanly but don't want to have a bunch of intermediate merge commits. -With `rerere` turned on you can merge occasionally, resolve the conflicts, then back out the merge. +One of the examples that is mentioned in the documentation is when you want to make sure a long-lived topic branch will ultimately merge cleanly, but you don't want to have a bunch of intermediate merge commits cluttering up your commit history. +With `rerere` enabled, you can attempt the occasional merge, resolve the conflicts, then back out of the merge. If you do this continuously, then the final merge should be easy because `rerere` can just do everything for you automatically. This same tactic can be used if you want to keep a branch rebased so you don't have to deal with the same rebasing conflicts each time you do it. -Or if you want to take a branch that you merged and fixed a bunch of conflicts and then decide to rebase it instead - you likely won't have to do all the same conflicts again. +Or if you want to take a branch that you merged and fixed a bunch of conflicts and then decide to rebase it instead -- you likely won't have to do all the same conflicts again. -Another situation is where you merge a bunch of evolving topic branches together into a testable head occasionally, as the Git project itself often does. +Another application of `rerere` is where you merge a bunch of evolving topic branches together into a testable head occasionally, as the Git project itself often does. If the tests fail, you can rewind the merges and re-do them without the topic branch that made the tests fail without having to re-resolve the conflicts again. -To enable the `rerere` functionality, you simply have to run this config setting: +To enable `rerere` functionality, you simply have to run this config setting: [source,console] ---- $ git config --global rerere.enabled true ---- -You can also turn it on by creating the `.git/rr-cache` directory in a specific repository, but the config setting is clearer and it can be done globally. +You can also turn it on by creating the `.git/rr-cache` directory in a specific repository, but the config setting is clearer and enables that feature globally for you. Now let's see a simple example, similar to our previous one. Let's say we have a file named `hello.rb` that looks like this: @@ -76,7 +76,7 @@ $ git rerere status hello.rb ---- -And `git rerere diff` will show the current state of the resolution - what you started with to resolve and what you've resolved it to. +And `git rerere diff` will show the current state of the resolution -- what you started with to resolve and what you've resolved it to. [source,console] ---- @@ -99,7 +99,7 @@ $ git rerere diff end ---- -Also (and this isn't really related to `rerere`), you can use `ls-files -u` to see the conflicted files and the before, left and right versions: +Also (and this isn't really related to `rerere`), you can use `git ls-files -u` to see the conflicted files and the before, left and right versions: [source,console] ---- @@ -109,7 +109,7 @@ $ git ls-files -u 100644 54336ba847c3758ab604876419607e9443848474 3 hello.rb ---- -Now you can resolve it to just be `puts 'hola mundo'` and you can run the `rerere diff` command again to see what rerere will remember: +Now you can resolve it to just be `puts 'hola mundo'` and you can run `git rerere diff` again to see what rerere will remember: [source,console] ---- @@ -146,7 +146,7 @@ You can see that it "Recorded resolution for FILE". image::images/rerere2.png[] Now, let's undo that merge and then rebase it on top of our master branch instead. -We can move our branch back by using `reset` as we saw in <<_git_reset>>. +We can move our branch back by using `git reset` as we saw in <>. [source,console] ---- @@ -207,7 +207,7 @@ index a440db6,54336ba..0000000 image::images/rerere3.png[] -You can also recreate the conflicted file state with the `checkout` command: +You can also recreate the conflicted file state with `git checkout`: [source,console] ---- @@ -224,8 +224,8 @@ def hello end ---- -We saw an example of this in <<_advanced_merging>>. -For now though, let's re-resolve it by just running `rerere` again: +We saw an example of this in <>. +For now though, let's re-resolve it by just running `git rerere` again: [source,console] ---- diff --git a/book/07-git-tools/sections/reset.asc b/book/07-git-tools/sections/reset.asc index e7b1091ac..59be38cb6 100644 --- a/book/07-git-tools/sections/reset.asc +++ b/book/07-git-tools/sections/reset.asc @@ -1,15 +1,15 @@ [[_git_reset]] === Reset Demystified -Before moving on to more specialized tools, let's talk about `reset` and `checkout`. +Before moving on to more specialized tools, let's talk about the Git `reset` and `checkout` commands. These commands are two of the most confusing parts of Git when you first encounter them. -They do so many things, that it seems hopeless to actually understand them and employ them properly. +They do so many things that it seems hopeless to actually understand them and employ them properly. For this, we recommend a simple metaphor. ==== The Three Trees An easier way to think about `reset` and `checkout` is through the mental frame of Git being a content manager of three different trees. -By ``tree'' here we really mean ``collection of files'', not specifically the data structure. +By ``tree'' here, we really mean ``collection of files'', not specifically the data structure. (There are a few cases where the index doesn't exactly act like a tree, but for our purposes it is easier to think about it this way for now.) Git as a system manages and manipulates three trees in its normal operation: @@ -26,7 +26,7 @@ Git as a system manages and manipulates three trees in its normal operation: HEAD is the pointer to the current branch reference, which is in turn a pointer to the last commit made on that branch. That means HEAD will be the parent of the next commit that is created. -It's generally simplest to think of HEAD as the snapshot of *your last commit*. +It's generally simplest to think of HEAD as the snapshot of *your last commit on that branch*. In fact, it's pretty easy to see what that snapshot looks like. Here is an example of getting the actual directory listing and SHA-1 checksums for each file in the HEAD snapshot: @@ -46,12 +46,12 @@ $ git ls-tree -r HEAD 040000 tree 99f1a6d12cb4b6f19... lib ---- -The `cat-file` and `ls-tree` commands are ``plumbing'' commands that are used for lower level things and not really used in day-to-day work, but they help us see what's going on here. +The Git `cat-file` and `ls-tree` commands are ``plumbing'' commands that are used for lower level things and not really used in day-to-day work, but they help us see what's going on here. [[_the_index]] ===== The Index -The Index is your *proposed next commit*. +The _index_ is your *proposed next commit*. We've also been referring to this concept as Git's ``Staging Area'' as this is what Git looks at when you run `git commit`. Git populates this index with a list of all the file contents that were last checked out into your working directory and what they looked like when they were originally checked out. @@ -65,16 +65,16 @@ $ git ls-files -s 100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0 lib/simplegit.rb ---- -Again, here we're using `ls-files`, which is more of a behind the scenes command that shows you what your index currently looks like. +Again, here we're using `git ls-files`, which is more of a behind the scenes command that shows you what your index currently looks like. -The index is not technically a tree structure – it's actually implemented as a flattened manifest – but for our purposes it's close enough. +The index is not technically a tree structure -- it's actually implemented as a flattened manifest -- but for our purposes it's close enough. ===== The Working Directory -Finally, you have your working directory. +Finally, you have your _working directory_ (also commonly referred to as the ``working tree''). The other two trees store their content in an efficient but inconvenient manner, inside the `.git` folder. -The Working Directory unpacks them into actual files, which makes it much easier for you to edit them. -Think of the Working Directory as a *sandbox*, where you can try changes out before committing them to your staging area (index) and then to history. +The working directory unpacks them into actual files, which makes it much easier for you to edit them. +Think of the working directory as a *sandbox*, where you can try changes out before committing them to your staging area (index) and then to history. [source,console] ---- @@ -90,41 +90,40 @@ $ tree ==== The Workflow -Git's main purpose is to record snapshots of your project in successively better states, by manipulating these three trees. +Git's typical workflow is to record snapshots of your project in successively better states, by manipulating these three trees. image::images/reset-workflow.png[] Let's visualize this process: say you go into a new directory with a single file in it. We'll call this *v1* of the file, and we'll indicate it in blue. -Now we run `git init`, which will create a Git repository with a HEAD reference which points to an unborn branch (`master` doesn't exist yet). +Now we run `git init`, which will create a Git repository with a HEAD reference which points to the unborn `master` branch. image::images/reset-ex1.png[] -At this point, only the Working Directory tree has any content. +At this point, only the working directory tree has any content. -Now we want to commit this file, so we use `git add` to take content in the Working Directory and copy it to the Index. +Now we want to commit this file, so we use `git add` to take content in the working directory and copy it to the index. image::images/reset-ex2.png[] -Then we run `git commit`, which takes the contents of the Index and saves it as a permanent snapshot, creates a commit object which points to that snapshot, and updates `master` to point to that commit. +Then we run `git commit`, which takes the contents of the index and saves it as a permanent snapshot, creates a commit object which points to that snapshot, and updates `master` to point to that commit. image::images/reset-ex3.png[] If we run `git status`, we'll see no changes, because all three trees are the same. Now we want to make a change to that file and commit it. -We'll go through the same process; first we change the file in our working directory. +We'll go through the same process; first, we change the file in our working directory. Let's call this *v2* of the file, and indicate it in red. image::images/reset-ex4.png[] -If we run `git status` right now, we'll see the file in red as ``Changes not staged for commit,'' because that entry differs between the Index and the Working Directory. -Next we run `git add` on it to stage it into our Index. +If we run `git status` right now, we'll see the file in red as ``Changes not staged for commit,'' because that entry differs between the index and the working directory. +Next we run `git add` on it to stage it into our index. image::images/reset-ex5.png[] -At this point if we run `git status` we will see the file in green -under ``Changes to be committed'' because the Index and HEAD differ – that is, our proposed next commit is now different from our last commit. +At this point, if we run `git status`, we will see the file in green under ``Changes to be committed'' because the index and HEAD differ -- that is, our proposed next commit is now different from our last commit. Finally, we run `git commit` to finalize the commit. image::images/reset-ex6.png[] @@ -132,7 +131,7 @@ image::images/reset-ex6.png[] Now `git status` will give us no output, because all three trees are the same again. Switching branches or cloning goes through a similar process. -When you checkout a branch, it changes *HEAD* to point to the new branch ref, populates your *Index* with the snapshot of that commit, then copies the contents of the *Index* into your *Working Directory*. +When you checkout a branch, it changes *HEAD* to point to the new branch ref, populates your *index* with the snapshot of that commit, then copies the contents of the *index* into your *working Directory*. ==== The Role of Reset @@ -160,14 +159,14 @@ With `reset --soft`, it will simply stop there. Now take a second to look at that diagram and realize what happened: it essentially undid the last `git commit` command. When you run `git commit`, Git creates a new commit and moves the branch that HEAD points to up to it. -When you `reset` back to `HEAD~` (the parent of HEAD), you are moving the branch back to where it was, without changing the Index or Working Directory. -You could now update the Index and run `git commit` again to accomplish what `git commit --amend` would have done (see <<_git_amend>>). +When you `reset` back to `HEAD~` (the parent of HEAD), you are moving the branch back to where it was, without changing the index or working directory. +You could now update the index and run `git commit` again to accomplish what `git commit --amend` would have done (see <<_git_amend>>). ===== Step 2: Updating the Index (--mixed) -Note that if you run `git status` now you'll see in green the difference between the Index and what the new HEAD is. +Note that if you run `git status` now you'll see in green the difference between the index and what the new HEAD is. -The next thing `reset` will do is to update the Index with the contents of whatever snapshot HEAD now points to. +The next thing `reset` will do is to update the index with the contents of whatever snapshot HEAD now points to. image::images/reset-mixed.png[] @@ -179,7 +178,7 @@ You rolled back to before you ran all your `git add` and `git commit` commands. ===== Step 3: Updating the Working Directory (--hard) -The third thing that `reset` will do is to make the Working Directory look like the Index. +The third thing that `reset` will do is to make the working directory look like the index. If you use the `--hard` option, it will continue to this stage. image::images/reset-hard.png[] @@ -188,7 +187,7 @@ So let's think about what just happened. You undid your last commit, the `git add` and `git commit` commands, *and* all the work you did in your working directory. It's important to note that this flag (`--hard`) is the only way to make the `reset` command dangerous, and one of the very few cases where Git will actually destroy data. -Any other invocation of `reset` can be pretty easily undone, but the `--hard` option cannot, since it forcibly overwrites files in the Working Directory. +Any other invocation of `reset` can be pretty easily undone, but the `--hard` option cannot, since it forcibly overwrites files in the working directory. In this particular case, we still have the *v3* version of our file in a commit in our Git DB, and we could get it back by looking at our `reflog`, but if we had not committed it, Git still would have overwritten the file and it would be unrecoverable. ===== Recap @@ -196,23 +195,23 @@ In this particular case, we still have the *v3* version of our file in a commit The `reset` command overwrites these three trees in a specific order, stopping when you tell it to: 1. Move the branch HEAD points to _(stop here if `--soft`)_ -2. Make the Index look like HEAD _(stop here unless `--hard`)_ -3. Make the Working Directory look like the Index +2. Make the index look like HEAD _(stop here unless `--hard`)_ +3. Make the working directory look like the index ==== Reset With a Path That covers the behavior of `reset` in its basic form, but you can also provide it with a path to act upon. If you specify a path, `reset` will skip step 1, and limit the remainder of its actions to a specific file or set of files. -This actually sort of makes sense – HEAD is just a pointer, and you can't point to part of one commit and part of another. -But the Index and Working directory _can_ be partially updated, so reset proceeds with steps 2 and 3. +This actually sort of makes sense -- HEAD is just a pointer, and you can't point to part of one commit and part of another. +But the index and working directory _can_ be partially updated, so reset proceeds with steps 2 and 3. So, assume we run `git reset file.txt`. This form (since you did not specify a commit SHA-1 or branch, and you didn't specify `--soft` or `--hard`) is shorthand for `git reset --mixed HEAD file.txt`, which will: 1. Move the branch HEAD points to _(skipped)_ -2. Make the Index look like HEAD _(stop here)_ +2. Make the index look like HEAD _(stop here)_ -So it essentially just copies `file.txt` from HEAD to the Index. +So it essentially just copies `file.txt` from HEAD to the index. image::images/reset-path1.png[] @@ -222,22 +221,22 @@ If we look at the diagram for that command and think about what `git add` does, image::images/reset-path2.png[] This is why the output of the `git status` command suggests that you run this to unstage a file. -(See <<_unstaging>> for more on this.) +(See <> for more on this.) We could just as easily not let Git assume we meant ``pull the data from HEAD'' by specifying a specific commit to pull that file version from. We would just run something like `git reset eb43bf file.txt`. image::images/reset-path3.png[] -This effectively does the same thing as if we had reverted the content of the file to *v1* in the Working Directory, ran `git add` on it, then reverted it back to *v3* again (without actually going through all those steps). -If we run `git commit` now, it will record a change that reverts that file back to *v1*, even though we never actually had it in our Working Directory again. +This effectively does the same thing as if we had reverted the content of the file to *v1* in the working directory, ran `git add` on it, then reverted it back to *v3* again (without actually going through all those steps). +If we run `git commit` now, it will record a change that reverts that file back to *v1*, even though we never actually had it in our working directory again. It's also interesting to note that like `git add`, the `reset` command will accept a `--patch` option to unstage content on a hunk-by-hunk basis. So you can selectively unstage or revert content. ==== Squashing -Let's look at how to do something interesting with this newfound power – squashing commits. +Let's look at how to do something interesting with this newfound power -- squashing commits. Say you have a series of commits with messages like ``oops.'', ``WIP'' and ``forgot this file''. You can use `reset` to quickly and easily squash them into a single commit that makes you look really smart. @@ -248,7 +247,7 @@ The second commit was a work in progress and you want to squash it down. image::images/reset-squash-r1.png[] -You can run `git reset --soft HEAD~2` to move the HEAD branch back to an older commit (the first commit you want to keep): +You can run `git reset --soft HEAD~2` to move the HEAD branch back to an older commit (the most recent commit you want to keep): image::images/reset-squash-r2.png[] @@ -269,11 +268,11 @@ Like `reset`, `checkout` manipulates the three trees, and it is a bit different Running `git checkout [branch]` is pretty similar to running `git reset --hard [branch]` in that it updates all three trees for you to look like `[branch]`, but there are two important differences. First, unlike `reset --hard`, `checkout` is working-directory safe; it will check to make sure it's not blowing away files that have changes to them. -Actually, it's a bit smarter than that – it tries to do a trivial merge in the Working Directory, so all of the files you _haven't_ changed in will be updated. +Actually, it's a bit smarter than that -- it tries to do a trivial merge in the working directory, so all of the files you _haven't_ changed will be updated. `reset --hard`, on the other hand, will simply replace everything across the board without checking. -The second important difference is how it updates HEAD. -Where `reset` will move the branch that HEAD points to, `checkout` will move HEAD itself to point to another branch. +The second important difference is how `checkout` updates HEAD. +Whereas `reset` will move the branch that HEAD points to, `checkout` will move HEAD itself to point to another branch. For instance, say we have `master` and `develop` branches which point at different commits, and we're currently on `develop` (so HEAD points to it). If we run `git reset master`, `develop` itself will now point to the same commit that `master` does. @@ -289,7 +288,7 @@ image::images/reset-checkout.png[] The other way to run `checkout` is with a file path, which, like `reset`, does not move HEAD. It is just like `git reset [branch] file` in that it updates the index with that file at that commit, but it also overwrites the file in the working directory. -It would be exactly like `git reset --hard [branch] file` (if `reset` would let you run that) – it's not working-directory safe, and it does not move HEAD. +It would be exactly like `git reset --hard [branch] file` (if `reset` would let you run that) -- it's not working-directory safe, and it does not move HEAD. Also, like `git reset` and `git add`, `checkout` will accept a `--patch` option to allow you to selectively revert file contents on a hunk-by-hunk basis. @@ -299,7 +298,7 @@ Hopefully now you understand and feel more comfortable with the `reset` command, Here's a cheat-sheet for which commands affect which trees. The ``HEAD'' column reads ``REF'' if that command moves the reference (branch) that HEAD points to, and ``HEAD'' if it moves HEAD itself. -Pay especial attention to the 'WD Safe?' column – if it says *NO*, take a second to think before running that command. +Pay especial attention to the 'WD Safe?' column -- if it says *NO*, take a second to think before running that command. [options="header", cols="3,1,1,1,1"] |================================ @@ -308,8 +307,8 @@ Pay especial attention to the 'WD Safe?' column – if it says *NO*, take a seco | `reset --soft [commit]` | REF | NO | NO | YES | `reset [commit]` | REF | YES | NO | YES | `reset --hard [commit]` | REF | YES | YES | *NO* -| `checkout [commit]` | HEAD | YES | YES | YES +| `checkout ` | HEAD | YES | YES | YES | *File Level* | | | | -| `reset (commit) [file]` | NO | YES | NO | YES -| `checkout (commit) [file]` | NO | YES | YES | *NO* +| `reset [commit] ` | NO | YES | NO | YES +| `checkout [commit] ` | NO | YES | YES | *NO* |================================ diff --git a/book/07-git-tools/sections/revision-selection.asc b/book/07-git-tools/sections/revision-selection.asc index a141bd10e..14fb23736 100644 --- a/book/07-git-tools/sections/revision-selection.asc +++ b/book/07-git-tools/sections/revision-selection.asc @@ -1,19 +1,19 @@ [[_revision_selection]] === Revision Selection -Git allows you to specify specific commits or a range of commits in several ways. -They aren’t necessarily obvious but are helpful to know. +Git allows you to refer to a single commit, set of commits, or range of commits in a number of ways. +They aren't necessarily obvious but are helpful to know. ==== Single Revisions -You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. -This section outlines the various ways you can refer to a single commit. +You can obviously refer to any single commit by its full, 40-character SHA-1 hash, but there are more human-friendly ways to refer to commits as well. +This section outlines the various ways you can refer to any commit. ==== Short SHA-1 -Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous – that is, only one object in the current repository begins with that partial SHA-1. +Git is smart enough to figure out what commit you're referring to if you provide the first few characters of the SHA-1 hash, as long as that partial hash is at least four characters long and unambiguous; that is, no other object in the object database can have a hash that begins with the same prefix. -For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: +For example, to examine a specific commit where you know you added certain functionality, you might first run the `git log` command to locate the commit: [source,console] ---- @@ -38,7 +38,8 @@ Date: Thu Dec 11 14:58:32 2008 -0800 added some blame and merge stuff ---- -In this case, choose `1c002dd...`. If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): +In this case, say you're interested in the commit whose hash begins with `1c002dd...`. +You can inspect that commit with any of the following variations of `git show` (assuming the shorter versions are unambiguous): [source,console] ---- @@ -59,18 +60,17 @@ a11bef0 first commit ---- Generally, eight to ten characters are more than enough to be unique within a project. - -As an example, the Linux kernel, which is a pretty large project with over 450k commits and 3.6 million objects, has no two objects whose SHA-1s overlap more than the first 11 characters. +For example, as of February 2019, the Linux kernel (which is a fairly sizable project) has over 875,000 commits and almost seven million objects in its object database, with no two objects whose SHA-1s are identical in the first 12 characters. [NOTE] .A SHORT NOTE ABOUT SHA-1 ==== -A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. +A lot of people become concerned at some point that they will, by random happenstance, have two distinct objects in their repository that hash to the same SHA-1 value. What then? -If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. -If you try to check out that object again at some point, you’ll always get the data of the first object. +If you do happen to commit an object that hashes to the same SHA-1 value as a previous _different_ object in your repository, Git will see the previous object already in your Git database, assume it was already written and simply reuse it. +If you try to check out that object again at some point, you'll always get the data of the first object. However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. @@ -78,19 +78,19 @@ The number of randomly hashed objects needed to ensure a 50% probability of a si (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160))`. 2^80^ is 1.2 x 10^24^ or 1 million billion billion. -That’s 1,200 times the number of grains of sand on the earth. +That's 1,200 times the number of grains of sand on the earth. + +Here's an example to give you an idea of what it would take to get a SHA-1 collision. +If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (6.5 million Git objects) and pushing it into one enormous Git repository, it would take roughly 2 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. +Thus, a SHA-1 collision is less likely than every member of your programming team being attacked and killed by wolves in unrelated incidents on the same night. -Here’s an example to give you an idea of what it would take to get a SHA-1 collision. -If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (3.6 million Git objects) and pushing it into one enormous Git repository, it would take roughly 2 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. -A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. ==== [[_branch_references]] ==== Branch References -The most straightforward way to specify a commit requires that it has a branch reference pointed at it. -Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. -For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: +One straightforward way to refer to a particular commit is if it's the commit at the tip of a branch; in that case, you can simply use the branch name in any Git command that expects a reference to a commit. +For instance, if you want to examine the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to commit `ca82a6d...`: [source,console] ---- @@ -99,8 +99,8 @@ $ git show topic1 ---- If you want to see which specific SHA-1 a branch points to, or if you want to see what any of these examples boils down to in terms of SHA-1s, you can use a Git plumbing tool called `rev-parse`. -You can see <<_git_internals>> for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. -However, it can be helpful sometimes when you need to see what’s really going on. +You can see <> for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn't designed to be used in day-to-day operations. +However, it can be helpful sometimes when you need to see what's really going on. Here you can run `rev-parse` on your branch. [source,console] @@ -112,7 +112,7 @@ ca82a6dff817ec66f44342007202690a93763949 [[_git_reflog]] ==== RefLog Shortnames -One of the things Git does in the background while you’re working away is keep a ``reflog'' – a log of where your HEAD and branch references have been for the last few months. +One of the things Git does in the background while you're working away is keep a ``reflog'' -- a log of where your HEAD and branch references have been for the last few months. You can see your reflog by using `git reflog`: @@ -120,7 +120,7 @@ You can see your reflog by using `git reflog`: ---- $ git reflog 734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated -d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. +d921970 HEAD@{1}: merge phedders/rdocs: Merge made by the 'recursive' strategy. 1c002dd HEAD@{2}: commit: added some blame and merge stuff 1c36188 HEAD@{3}: rebase -i (squash): updating HEAD 95df984 HEAD@{4}: commit: # This is a combination of two commits. @@ -129,8 +129,8 @@ d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. ---- Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. -And you can specify older commits with this data, as well. -If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: +You can use your reflog data to refer to older commits as well. +For example, if you want to see the fifth prior value of the HEAD of your repository, you can use the `@{5}` reference that you see in the reflog output: [source,console] ---- @@ -145,8 +145,8 @@ For instance, to see where your `master` branch was yesterday, you can type $ git show master@{yesterday} ---- -That shows you where the branch tip was yesterday. -This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. +That would show you where tip of your `master` branch was yesterday. +This technique only works for data that's still in your reflog, so you can't use it to look for commits older than a few months. To see reflog information formatted like the `git log` output, you can run `git log -g`: @@ -170,14 +170,20 @@ Date: Thu Dec 11 15:08:43 2008 -0800 Merge commit 'phedders/rdocs' ---- -It’s important to note that the reflog information is strictly local – it’s a log of what you’ve done in your repository. -The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you'll have an empty reflog, as no activity has occurred yet in your repository. -Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago – if you cloned it five minutes ago, you’ll get no results. +It's important to note that reflog information is strictly local -- it's a log only of what _you've_ done in _your_ repository. +The references won't be the same on someone else's copy of the repository; also, right after you initially clone a repository, you'll have an empty reflog, as no activity has occurred yet in your repository. +Running `git show HEAD@{2.months.ago}` will show you the matching commit only if you cloned the project at least two months ago -- if you cloned it any more recently than that, you'll see only your first local commit. + +[TIP] +.Think of the reflog as Git's version of shell history +==== +If you have a UNIX or Linux background, you can think of the reflog as Git's version of shell history, which emphasizes that what's there is clearly relevant only for you and your ``session'', and has nothing to do with anyone else who might be working on the same machine. +==== ==== Ancestry References The other main way to specify a commit is via its ancestry. -If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. +If you place a `^` (caret) at the end of a reference, Git resolves it to mean the parent of that commit. Suppose you look at the history of your project: [source,console] @@ -206,9 +212,24 @@ Date: Thu Dec 11 15:08:43 2008 -0800 Merge commit 'phedders/rdocs' ---- -You can also specify a number after the `^` – for example, `d921970^2` means ``the second parent of d921970.'' -This syntax is only useful for merge commits, which have more than one parent. -The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: +[NOTE] +.Escaping the caret on Windows +==== + +On Windows in `cmd.exe`, `^` is a special character and needs to be treated differently. +You can either double it or put the commit reference in quotes: + +[source,console] +---- +$ git show HEAD^ # will NOT work on Windows +$ git show HEAD^^ # OK +$ git show "HEAD^" # OK +---- + +==== + +You can also specify a number after the `^` to identify _which_ parent you want; for example, `d921970^2` means ``the second parent of d921970.'' +This syntax is useful only for merge commits, which have more than one parent -- the _first_ parent of a merge commit is from the branch you were on when you merged (frequently `master`), while the _second_ parent of a merge commit is from the branch that was merged (say, `topic`): [source,console] ---- @@ -227,10 +248,10 @@ Date: Wed Dec 10 22:22:03 2008 +0000 Some rdoc changes ---- -The other main ancestry specification is the `~`. +The other main ancestry specification is the `~` (tilde). This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. -`HEAD~2` means ``the first parent of the first parent,'' or ``the grandparent'' – it traverses the first parents the number of times you specify. +`HEAD~2` means ``the first parent of the first parent,'' or ``the grandparent'' -- it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be [source,console] @@ -243,11 +264,11 @@ Date: Fri Nov 7 13:47:59 2008 -0500 ignore *.gem ---- -This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: +This can also be written `HEAD~~~`, which again is the first parent of the first parent of the first parent: [source,console] ---- -$ git show HEAD^^^ +$ git show HEAD~~~ commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d Author: Tom Preston-Werner Date: Fri Nov 7 13:47:59 2008 -0500 @@ -255,27 +276,27 @@ Date: Fri Nov 7 13:47:59 2008 -0500 ignore *.gem ---- -You can also combine these syntaxes – you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. +You can also combine these syntaxes -- you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. [[_commit_ranges]] ==== Commit Ranges -Now that you can specify individual commits, let’s see how to specify ranges of commits. -This is particularly useful for managing your branches – if you have a lot of branches, you can use range specifications to answer questions such as, ``What work is on this branch that I haven’t yet merged into my main branch?'' +Now that you can specify individual commits, let's see how to specify ranges of commits. +This is particularly useful for managing your branches -- if you have a lot of branches, you can use range specifications to answer questions such as, ``What work is on this branch that I haven't yet merged into my main branch?'' ===== Double Dot The most common range specification is the double-dot syntax. -This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. +This basically asks Git to resolve a range of commits that are reachable from one commit but aren't reachable from another. For example, say you have a commit history that looks like <>. [[double_dot]] .Example history for range selection. image::images/double-dot.png[Example history for range selection.] -You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. -You can ask Git to show you a log of just those commits with `master..experiment` – that means ``all commits reachable by experiment that aren’t reachable by master.'' -For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: +Say you want to see what is in your `experiment` branch that hasn't yet been merged into your `master` branch. +You can ask Git to show you a log of just those commits with `master..experiment` -- that means ``all commits reachable from experiment that aren't reachable from master.'' +For the sake of brevity and clarity in these examples, the letters of the commit objects from the diagram are used in place of the actual log output in the order that they would display: [source,console] ---- @@ -284,7 +305,7 @@ D C ---- -If, on the other hand, you want to see the opposite – all commits in `master` that aren’t in `experiment` – you can reverse the branch names. +If, on the other hand, you want to see the opposite -- all commits in `master` that aren't in `experiment` -- you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: [source,console] @@ -294,24 +315,24 @@ F E ---- -This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. -Another very frequent use of this syntax is to see what you’re about to push to a remote: +This is useful if you want to keep the `experiment` branch up to date and preview what you're about to merge. +Another frequent use of this syntax is to see what you're about to push to a remote: [source,console] ---- $ git log origin/master..HEAD ---- -This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. +This command shows you any commits in your current branch that aren't in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. -You can also leave off one side of the syntax to have Git assume HEAD. -For example, you can get the same results as in the previous example by typing `git log origin/master..` – Git substitutes HEAD if one side is missing. +You can also leave off one side of the syntax to have Git assume `HEAD`. +For example, you can get the same results as in the previous example by typing `git log origin/master..` -- Git substitutes `HEAD` if one side is missing. ===== Multiple Points -The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. -Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. -Thus these three commands are equivalent: +The double-dot syntax is useful as a shorthand, but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren't in the branch you're currently on. +Git allows you to do this by using either the `^` character or `--not` before any reference from which you don't want to see reachable commits. +Thus, the following three commands are equivalent: [source,console] ---- @@ -321,7 +342,7 @@ $ git log refB --not refA ---- This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. -For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: +For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can use either of: [source,console] ---- @@ -334,9 +355,9 @@ This makes for a very powerful revision query system that should help you figure [[_triple_dot]] ===== Triple Dot -The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. +The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by _either_ of two references but not by both of them. Look back at the example commit history in <>. -If you want to see what is in `master` or `experiment` but not any common references, you can run +If you want to see what is in `master` or `experiment` but not any common references, you can run: [source,console] ---- @@ -350,7 +371,7 @@ C Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. -This helps make the data more useful: +This helps make the output more useful: [source,console] ---- diff --git a/book/07-git-tools/sections/rewriting-history.asc b/book/07-git-tools/sections/rewriting-history.asc index 9819e0900..86bcbb10e 100644 --- a/book/07-git-tools/sections/rewriting-history.asc +++ b/book/07-git-tools/sections/rewriting-history.asc @@ -1,54 +1,76 @@ [[_rewriting_history]] === Rewriting History -Many times, when working with Git, you may want to revise your commit history for some reason. +Many times, when working with Git, you may want to revise your local commit history. One of the great things about Git is that it allows you to make decisions at the last possible moment. -You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. -This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely – all before you share your work with others. +You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn't mean to be working on something yet with `git stash`, and you can rewrite commits that already happened so they look like they happened in a different way. +This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely -- all before you share your work with others. -In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others. +In this section, you'll see how to accomplish these tasks so that you can make your commit history look the way you want before you share it with others. + +[NOTE] +.Don't push your work until you're happy with it +==== +One of the cardinal rules of Git is that, since so much work is local within your clone, you have a great deal of freedom to rewrite your history _locally_. +However, once you push your work, it is a different story entirely, and you should consider pushed work as final unless you have good reason to change it. +In short, you should avoid pushing your work until you're happy with it and ready to share it with the rest of the world. +==== [[_git_amend]] ==== Changing the Last Commit -Changing your last commit is probably the most common rewriting of history that you’ll do. -You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. +Changing your most recent commit is probably the most common rewriting of history that you'll do. +You'll often want to do two basic things to your last commit: simply change the commit message, or change the actual content of the commit by adding, removing and modifying files. -If you only want to modify your last commit message, it’s very simple: +If you simply want to modify your last commit message, that's easy: [source,console] ---- $ git commit --amend ---- -That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. -When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit. +The command above loads the previous commit message into an editor session, where you can make changes to the message, save those changes and exit. +When you save and close the editor, the editor writes a new commit containing that updated commit message and makes it your new last commit. -If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. -You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit. +If, on the other hand, you want to change the actual _content_ of your last commit, the process works basically the same way -- first make the changes you think you forgot, stage those changes, and the subsequent `git commit --amend` _replaces_ that last commit with your new, improved commit. You need to be careful with this technique because amending changes the SHA-1 of the commit. -It’s like a very small rebase – don’t amend your last commit if you’ve already pushed it. +It's like a very small rebase -- don't amend your last commit if you've already pushed it. + +[TIP] +.An amended commit may (or may not) need an amended commit message +==== +When you amend a commit, you have the opportunity to change both the commit message and the content of the commit. +If you amend the content of the commit substantially, you should almost certainly update the commit message to reflect that amended content. + +On the other hand, if your amendments are suitably trivial (fixing a silly typo or adding a file you forgot to stage) such that the earlier commit message is just fine, you can simply make the changes, stage them, and avoid the unnecessary editor session entirely with: + +[source,console] +---- +$ git commit --amend --no-edit +---- + +==== [[_changing_multiple]] ==== Changing Multiple Commit Messages To modify a commit that is farther back in your history, you must move to more complex tools. -Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. +Git doesn't have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto. For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. -It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit: +It may be easier to remember the `~3` because you're trying to edit the last three commits, but keep in mind that you're actually designating four commits ago, the parent of the last commit you want to edit: [source,console] ---- $ git rebase -i HEAD~3 ---- -Remember again that this is a rebasing command – every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. -Don’t include any commit you’ve already pushed to a central server – doing so will confuse other developers by providing an alternate version of the same change. +Remember again that this is a rebasing command -- every commit in the range `HEAD~3..HEAD` with a changed message _and all of its descendants_ will be rewritten. +Don't include any commit you've already pushed to a central server -- doing so will confuse other developers by providing an alternate version of the same change. Running this command gives you a list of commits in your text editor that looks something like this: @@ -61,12 +83,20 @@ pick a5f4a0d added cat-file # Rebase 710f0f8..a5f4a0d onto 710f0f8 # # Commands: -# p, pick = use commit -# r, reword = use commit, but edit the commit message -# e, edit = use commit, but stop for amending -# s, squash = use commit, but meld into previous commit -# f, fixup = like "squash", but discard this commit's log message -# x, exec = run command (the rest of the line) using shell +# p, pick = use commit +# r, reword = use commit, but edit the commit message +# e, edit = use commit, but stop for amending +# s, squash = use commit, but meld into previous commit +# f, fixup = like "squash", but discard this commit's log message +# x, exec = run command (the rest of the line) using shell +# b, break = stop here (continue rebase later with 'git rebase --continue') +# d, drop = remove commit +# l, label