On Sun, Mar 15, 2020 at 10:39:23PM +0000, brian m. carlson wrote: > Git is an enormously flexible and powerful piece of software. However, > it can be intimidating for many users and there are a set of common > questions that users often ask. While we already have some new user > documentation, it's worth adding a FAQ to address common questions that > users often have. Even though some of this is addressed elsewhere in > the documentation, experience has shown that it is difficult for users > to find, so a centralized location is helpful. It's true that some of it is duplicated; if we're worried about the info getting out of sync, we might be able to do something like Documentation/config so we're pulling in a single piece of text to both places. > > Add such a FAQ and fill it with some common questions and answers. > While there are few entries now, we can expand it in the future to cover > more things as we find new questions that users have. Let's also add > section markers so that people answering questions can directly link > users to the proper answer. > > The FAQ also addresses common configuration questions that apply not > only to Git as an independent piece of software but also the ecosystem > of CI tools and hosting providers that people use, since these are the > source of common questions. An attempt has been made to avoid > mentioning any particular provider or tool, but to nevertheless cover > common configurations that apply to a wide variety of such tools. > > Note that the long lines for certain questions are required, since > Asciidoctor does not permit broken lines there. > --- > Documentation/Makefile | 1 + > Documentation/gitfaq.txt | 330 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 331 insertions(+) > create mode 100644 Documentation/gitfaq.txt > > diff --git a/Documentation/Makefile b/Documentation/Makefile > index 8fe829cc1b..59e6ce3a2a 100644 > --- a/Documentation/Makefile > +++ b/Documentation/Makefile > @@ -30,6 +30,7 @@ MAN7_TXT += gitcredentials.txt > MAN7_TXT += gitcvs-migration.txt > MAN7_TXT += gitdiffcore.txt > MAN7_TXT += giteveryday.txt > +MAN7_TXT += gitfaq.txt > MAN7_TXT += gitglossary.txt > MAN7_TXT += gitnamespaces.txt > MAN7_TXT += gitremote-helpers.txt > diff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt > new file mode 100644 > index 0000000000..318e4dd648 > --- /dev/null > +++ b/Documentation/gitfaq.txt > @@ -0,0 +1,330 @@ > +gitfaq(7) > +========= > + > +NAME > +---- > +gitfaq - Frequently asked questions about using Git > + > +SYNOPSIS > +-------- > +gitfaq > + > +DESCRIPTION > +----------- > + > +The examples in this FAQ assume a standard POSIX shell, like `bash` or `dash`, > +and a user, A U Thor, who has the account `author` on the hosting provider > +`git.example.org`. > + > +Configuration > +------------- > + > +[[user-name]] > +What should I put in `user.name`?:: > + You should put your personal name; that is, the name that other humans call > + you. This will be the name portion that is stored in every commit you make. I like the direction but I think it is still a little unclear. Other humans call me Emily, but I want to put "Emily Shaffer" in my user.name. I wonder how we can suggest full name in a way that's as universal as "the name that other humans call you"? I think I got around to this point by using examples when covering the SOB in MyFirstContribution, so I don't have a good answer off the top of my head. > ++ > +This configuration doesn't have any effect on authenticating to remote > +services; for that, see `credential.username` in linkgit:git-config[1]. > + > +[[http-postbuffer]] > +What does `http.postBuffer` really do?:: > + This option changes the size of the buffer that Git uses when pushing data to > + a remote over HTTP or HTTPS. If the data is larger than this size, libcurl, > + which handles the HTTP support for Git, will use chunked transfer encoding > + since it isn't known ahead of time what the size of the pushed data will be. > ++ > +Leaving this value at the default size is fine unless you know that either the > +remote server or a proxy in the middle doesn't support HTTP/1.1 (which > +introduced the chunked transfer encoding) or is known to be broken with chunked > +data. People often suggest this as a solution for generic push problems, but > +since almost every server and proxy supports at least HTTP/1.1, raising this > +value usually doesn't solve most push problems. A server or proxy that didn't This might be burying the lede a little for someone frantically skimming for an answer. If I was really spinning my wheels I might read "People often suggest this as a solution for generic push problems" and go try it. Is "People often (erroneously) suggest this ..." too verbose? > +correctly support HTTP/1.1 and chunked transfer encoding wouldn't be that useful > +on the Internet today, since it would break lots of traffic. > ++ > +Note that increasing this value will increase the memory used on every relevant > +push that Git does over HTTP or HTTPS, since the entire buffer is allocated > +regardless of whether or not it is all used. Thus, it's best to leave it at the > +default unless you are sure you need a different value. > + > +[[configure-editor]] > +How do I configure a different editor?:: > + If you haven't specified an editor specifically for Git, it will by default > + use the editor you've configured using the `VISUAL` or `EDITOR` environment > + variables, or if neither is specified, the system default (which is usually > + `vi`). Since some people find `vi` difficult to use, it may be desirable to > + change the editor used. > ++ > +If you want to configure a general editor for most programs which need one, you > +can edit your shell configuration (e.g., `~/.bashrc` or `~/.zshenv`) to contain > +a line setting the `EDITOR` or `VISUAL` environment variable to an appropriate > +value. For example, if you preferred the editor `nano`, then you could write > +the following: > ++ > +---- > +export VISUAL=nano > +---- I'll swallow my pride as a Vim user here and say that I think 'nano' is a good choice to reference directly here; it seems to fit right into the experience level this particular Q is targeting. Nice. > ++ > +If you want to configure an editor specifically for Git, you can either set the > +`core.editor` configuration value or the `GIT_EDITOR` environment variable. You > +can see linkgit:git-var[1] for details on the order in which these options are > +consulted. > ++ > +Note that in all cases, the editor value will be passed to the shell, so any > +arguments containing spaces should be appropriately quoted. Additionally, if > +your editor normally detaches from the terminal when invoked, you should specify > +it with an argument that makes it not do that, or else Git will not see any > +changes. An example of a configuration addressing both of these issues on > +Windows would be the configuration `"C:\Program Files\Vim\gvim.exe" --nofork`, > +which quotes the filename with spaces and specifies the `--nofork` option to > +avoid backgrounding the process. > + > +Credentials > +----------- > + > +[[http-credentials]] > +How do I specify my credentials when pushing over HTTP?:: > + The easiest way to do this is to use a credential helper via the > + `credential.helper` configuration. Most systems provide a standard choice to > + integrate with the system credential manager. For example, Git for Windows > + provides the `wincred` credential manager, macOS has the `osxkeychain` > + credential manager, and Unix systems with a standard desktop environment can > + use the `libsecret` credential manager. All of these store credentials in an > + encrypted store to keep your passwords or tokens secure. > ++ > +In addition, you can use the `store` credential manager which stores in a file > +in your home directory, or the `cache` credential manager, which does not > +permanently store your credentials, but does prevent you from being prompted for > +them for a certain period of time. > ++ > +You can also just enter your password when prompted, or you can place the > +password (which must be percent-encoded) in the URL. The latter option is not > +particularly secure and can lead to accidental exposure of credentials, so it is > +not recommended. > + > +[[http-credentials-environment]] > +How do I read a password or token from an environment variable?:: > + The `credential.helper` configuration option can also take an arbitrary shell > + command that produces the credential protocol on standard output. This is > + useful when passing credentials into a container, for example. > ++ > +Such a shell command can be specified by starting the option value with an > +exclamation point. If your password or token were stored in the `GIT_TOKEN`, > +you could run the following command to set your credential helper: > ++ > +---- > +$ git config credential.helper \ > + '!f() { echo username=author; echo "password=$GIT_TOKEN"; };f' > +---- > + > +[[http-reset-credentials]] > +How do I change the password or token I've saved in my credential manager?:: > + Usually, if the password or token is invalid, Git will erase it and prompt for > + a new one. However, there are times when this doesn't always happen. To > + change the password or token, you can erase the existing credentials and then > + Git will prompt for new ones. To erase credentials, use a syntax like the > + following (substituting your username and the hostname): > ++ > +---- > +$ echo url=https://author@xxxxxxxxxxxxxxx | git credential reject > +---- > + > +[[multiple-accounts-http]] > +How do I use multiple accounts with the same hosting provider using HTTP?:: > + Usually the easiest way to distinguish between these accounts is to use the > + username in the URL. For example, if you have the accounts `author` and > + `committer` on `git.example.org`, you can use the URLs > + https://author@xxxxxxxxxxxxxxx/org1/project1.git and > + https://committer@xxxxxxxxxxxxxxx/org2/project2.git. This way, when you use a > + credential helper, it will automatically try to look up the correct > + credentials for your account. If you already have a remote set up, you can > + change the URL with something like `git remote set-url origin > + https://author@xxxxxxxxxxxxxxx/org1/project1.git` (see linkgit:git-remote[1] > + for details). > + > +[[multiple-accounts-ssh]] > +How do I use multiple accounts with the same hosting provider using SSH?:: > + With most hosting providers that support SSH, a single key pair uniquely > + identifies a user. Therefore, to use multiple accounts, it's necessary to > + create a key pair for each account. If you're using a reasonably modern > + OpenSSH version, you can create a new key pair with something like `ssh-keygen > + -t ed25519 -f ~/.ssh/id_committer`. You can then register the public key (in > + this case, `~/.ssh/id_committer.pub`; note the `.pub`) with the hosting > + provider. > ++ > +Most hosting providers use a single SSH account for pushing; that is, all users > +push to the `git` account (e.g., `git@xxxxxxxxxxxxxxx`). If that's the case for > +your provider, you can set up multiple aliases in SSH to make it clear which key > +pair to use. For example, you could write something like the following, > +substituting the proper private key file: > ++ > +---- > +# This is the account for author on git.example.org. > +Host example_author > + HostName git.example.org > + User git > + # This is the key pair registered for author with git.example.org. > + IdentityFile ~/.ssh/id_author > + IdentitiesOnly yes > +# This is the committer for author on git.example.org. > +Host example_committer > + HostName git.example.org > + User git > + # This is the key pair registered for committer with git.example.org. > + IdentityFile ~/.ssh/id_committer > + IdentitiesOnly yes > +---- > ++ > +Then, you can adjust your push URL to use `git@example_author` or > +`git@example_committer` instead of `git@xxxxxxxxxxx` (e.g., `git remote set-url > +git@example_author:org1/project1.git`). > + > +Common Issues > +------------- > + > +[[last-commit-amend]] > +I've made a mistake in the last commit. How do I change it?:: > + You can make the appropriate change to your working tree, run `git add <file>` > + to stage it, and then `git commit --amend`. Your change will be included in > + the commit, and you'll be prompted to edit the commit message again; if you > + don't want to edit it, you can use the `--no-edit` option to `git commit` in > + addition, or just save and quit when your editor opens. > + > +[[undo-previous-change]] > +I've made a change with a bug and it's been included in the main branch. How should I undo it?:: > + The usual way to deal with this is to use `git revert`. This preserves the > + history that the original change was made and was a valuable contribution, but > + also introduces a new commit that undoes those changes because the original > + had a problem. The commit message of the revert indicates the commit which > + was reverted and can be edited to include an explanation as to why the revert > + was made. > + > +[[ignore-tracked-files]] > +How do I ignore changes to a tracked file?:: > + Git doesn't provide a way to do this. The reason is that if Git needs to > + overwrite this file, such as during a checkout, it doesn't know whether the > + changes to the file are precious and should be kept, or whether they are > + irrelevant and can safely be destroyed. Therefore, it has to take the safe > + route and always preserve them. > ++ > +Some people are tempted to use certain features of `git update-index`, namely > +the assume-unchanged and skip-worktree bits, but these don't work properly for > +this purpose and shouldn't be used this way. Not really on topic for this particular paragraph, but there are a lot of instances of "Some people ..." - in general, would it be less combative to say something like "It's tempting to..." or "It might seem like a good idea to..."? That way it feels less like "there are people who do X and they are wrong" and more like "X might seem like a good idea but it isn't". Or to put it another way, let's attack the bad idea, not the people who suggest it. > ++ > +If your goal is to modify a configuration file, it can often be helpful to have > +a file checked into the repository which is a template or set of defaults which > +can then be copied alongside and modified as appropriate. This second, modified > +file is usually ignored to prevent accidentally committing it. > + > +Hooks > +----- > + > +[[restrict-with-hooks]] > +How do I prevent users from making certain changes with hooks?:: > + The only safe place to make these changes is on the remote repository (i.e., > + the Git server), usually in the `pre-receive` hook or in a continuous > + integration (CI) system. These are the locations in which policy can be > + enforced effectively. > ++ > +Some people try to use `pre-commit` hooks (or, for commit messages, `commit-msg` > +hooks) to check these things, which is fine if you're working as a solo > +developer and want the tooling to help you. However, using hooks on a developer > +machine is not effective as a policy control because a user can bypass these > +hooks with `--no-verify` without being noticed (among various other ways). Git > +assumes that the user is in control of their local repositories and doesn't try > +to prevent this or tattle on the user. > ++ > +In addition, some advanced users find `pre-commit` hooks to be an impediment to > +workflows that use temporary commits to stage work in progress or that create > +fixup commits, so it's better to push these kinds of checks to the server > +anyway. > + > +Cross-Platform Issues > +~~~~~~~~~~~~~~~~~~~~~ > + > +[[windows-text-binary]] > +I'm on Windows and my text files are detected as binary.:: > + Git works best when you store text files as UTF-8. Many programs on Windows > + support UTF-8, but some do not and only use the little-endian UTF-16 format, > + which Git detects as binary. If you can't use UTF-8 with your programs, you > + can specify a working tree encoding that indicates which encoding your files > + should be checked out with, while still storing these files as UTF-8 in the > + repository. This allows tools like linkgit:git-diff[1] to work as expected, > + while still allowing your tools to work. > ++ > +To do so, you can specify a linkgit:gitattributes[5] pattern with with the > +`working-tree-encoding` attribute. For example, the following pattern sets all > +C files to use UTF-16LE-BOM, which is a common encoding on Windows: > ++ > +---- > +*.c working-tree-encoding=UTF-16LE-BOM > +---- > ++ > +You will need to run `git add --renormalize` to have this take effect. Note > +that if you are making these changes on a project that is used across platforms, > +you'll probably want to make it in a per-user configuration file or in the one > +in `$GIT_DIR/info/attributes`, since making it in a `.gitattributes` file in > +the repository will apply to all users of the repository. > ++ > +See the following entry for information about normalizing line endings as well, > +and see linkgit:gitattributes[5] for more information about attribute files. > + > +[[windows-diff-control-m]] > +I'm on Windows and git diff shows my files as having a `^M` at the end.:: > + By default, Git expects files to be stored with Unix line endings. As such, > + the carriage return (`^M`) that is part of a Windows line ending results is > + show because it is considered to be trailing whitespace. Git defaults to > + showing trailing whitespace only on new lines, not existing ones. > ++ > +You can store the files in the repository with Unix line endings and convert > +them automatically to your platform's line endings. To do that, set the > +configuration option `core.eol` to `native` and see the following entry for > +information about how to configure files as text or binary. > ++ > +You can also control this behavior with the `core.whitespace` setting if you > +don't wish to remove the carriage returns from your line endings. > + > +[[recommended-storage-settings]] > +What's the recommended way to store files in Git?:: > + While Git can store and handle any file of any type, there are some settings > + that work better than others. In general, we recommend that text files be > + stored in UTF-8 without a byte-order mark (BOM) with LF (Unix-style) endings. > + We also recommend the use of UTF-8 (again, without BOM) in commit messages. > + These are the settings that work best across platforms and with tools such as > + `git diff` and `git merge`. > ++ > +Additionally, if you have a choice between storage formats that are text based > +or non-text based, we recommend storing files in the text format and, if > +necessary, transforming them into the other format. For example, a text-based > +SQL dump with one record per line will work much better for diffing and merging > +than an actual database file. Similarly, text-based formats such as Markdown > +and AsciiDoc will work better than binary formats such as Microsoft Word and > +PDF. > ++ > +Similarly, storing binary dependencies (e.g., shared libraries or JAR files) or > +build products in the repository is generally not recommended. Dependencies and > +build products are best stored on an artifact or package server with only > +references, URLs, and hashes stored in the repository. > ++ > +We also recommend setting a link:gitattributes[5] file to explicitly mark which > +files are text and which are binary. If you want Git to guess, you can set the > +attribute `text=auto`. For example, the following might be appropriate in some > +projects: > ++ > +---- > +# By default, guess. > +* text=auto > +# Mark all C files as text. > +*.c text > +# Mark all JPEG files as binary. > +*.jpg binary > +---- > ++ > +These settings help tools pick the right format for output such as patches and > +result in files being checked out in the appropriate line ending for the > +platform. > + > +GIT > +--- > +Part of the linkgit:git[1] suite