1
0
mirror of https://github.com/k88hudson/git-flight-rules.git synced 2025-06-17 13:41:32 -03:00

11 Commits

Author SHA1 Message Date
69f7635ed1 Update README.md : Fix typo (#370) 2025-04-12 10:26:43 +12:00
405a57c6d4 chore: Update Vietnamese translation (#363) 2024-08-27 14:17:08 +12:00
f4dabebc83 Merge pull request #362 from lumynou5/change-author
Add method to change authors for multiple commits
2024-05-27 20:53:00 -03:00
449e36d21b Add information about filter-branch back 2024-05-21 11:05:33 +08:00
819b14a73f Add method to change authors for multiple commits 2024-05-14 13:58:41 +08:00
b752196266 Fix link in README_ja.md (#361) 2024-03-18 10:17:15 -04:00
1037756725 Adding Git cartoons by Allison Horst. (#360)
Adding https://allisonhorst.com/git-github. 

Also, alphabetized section.
2024-02-23 10:08:06 +11:00
e1fd8abce8 Improve (remove) "Unstaged Edits" (#358) 2023-09-27 10:35:07 -04:00
02cee38025 Fixed typos for internal and external links (#357)
* Update anchor link to `push.default` documentation

* Update anchor link to `rebase --merge` documentation

* Fix link typos
2023-07-21 13:41:29 -04:00
c3df156871 Clarify the use of --amend (#354)
Co-authored-by: Richard Littauer <richard.littauer@gmail.com>
2023-06-28 11:56:19 +02:00
0b1f7bcdaf Improve zh-TW (#352) 2023-06-28 11:51:46 +02:00
9 changed files with 647 additions and 252 deletions

119
README.md
View File

@ -57,20 +57,20 @@ All commands should work for at least git version 2.13.0. See the [git website](
- [I want to add changes in one file to two different commits](#i-want-to-add-changes-in-one-file-to-two-different-commits) - [I want to add changes in one file to two different commits](#i-want-to-add-changes-in-one-file-to-two-different-commits)
- [I staged too many edits, and I want to break them out into a separate commit](#i-staged-too-many-edits-and-i-want-to-break-them-out-into-a-separate-commit) - [I staged too many edits, and I want to break them out into a separate commit](#i-staged-too-many-edits-and-i-want-to-break-them-out-into-a-separate-commit)
- [I want to stage my unstaged edits, and unstage my staged edits](#i-want-to-stage-my-unstaged-edits-and-unstage-my-staged-edits) - [I want to stage my unstaged edits, and unstage my staged edits](#i-want-to-stage-my-unstaged-edits-and-unstage-my-staged-edits)
- [Unstaged Edits](#unstaged-edits) - [I want to unstage a specific staged file](#i-want-to-unstage-a-specific-staged-file)
- [I want to move my unstaged edits to a new branch](#i-want-to-move-my-unstaged-edits-to-a-new-branch) - [Discarding changes](#discarding-changes)
- [I want to move my unstaged edits to a different, existing branch](#i-want-to-move-my-unstaged-edits-to-a-different-existing-branch)
- [I want to discard my local uncommitted changes (staged and unstaged)](#i-want-to-discard-my-local-uncommitted-changes-staged-and-unstaged) - [I want to discard my local uncommitted changes (staged and unstaged)](#i-want-to-discard-my-local-uncommitted-changes-staged-and-unstaged)
- [I want to discard specific unstaged changes](#i-want-to-discard-specific-unstaged-changes) - [I want to discard specific unstaged changes](#i-want-to-discard-specific-unstaged-changes)
- [I want to discard specific unstaged files](#i-want-to-discard-specific-unstaged-files) - [I want to discard specific unstaged files](#i-want-to-discard-specific-unstaged-files)
- [I want to discard only my unstaged local changes](#i-want-to-discard-only-my-unstaged-local-changes) - [I want to discard only my unstaged local changes](#i-want-to-discard-only-my-unstaged-local-changes)
- [I want to discard all of my untracked files](#i-want-to-discard-all-of-my-untracked-files) - [I want to discard all of my untracked files](#i-want-to-discard-all-of-my-untracked-files)
- [I want to unstage a specific staged file](#i-want-to-unstage-a-specific-staged-file)
- [Branches](#branches) - [Branches](#branches)
- [I want to list all branches](#i-want-to-list-all-branches) - [I want to list all branches](#i-want-to-list-all-branches)
- [Create a branch from a commit](#create-a-branch-from-a-commit) - [Create a branch from a commit](#create-a-branch-from-a-commit)
- [I pulled from/into the wrong branch](#i-pulled-frominto-the-wrong-branch) - [I pulled from/into the wrong branch](#i-pulled-frominto-the-wrong-branch)
- [I want to discard local commits so my branch is the same as one on the server](#i-want-to-discard-local-commits-so-my-branch-is-the-same-as-one-on-the-server) - [I want to discard local commits so my branch is the same as one on the server](#i-want-to-discard-local-commits-so-my-branch-is-the-same-as-one-on-the-server)
- [I want to move my unstaged edits to a new branch](#i-want-to-move-my-unstaged-edits-to-a-new-branch)
- [I want to move my unstaged edits to a different, existing branch](#i-want-to-move-my-unstaged-edits-to-a-different-existing-branch)
- [I committed to main instead of a new branch](#i-committed-to-main-instead-of-a-new-branch) - [I committed to main instead of a new branch](#i-committed-to-main-instead-of-a-new-branch)
- [I want to keep the whole file from another ref-ish](#i-want-to-keep-the-whole-file-from-another-ref-ish) - [I want to keep the whole file from another ref-ish](#i-want-to-keep-the-whole-file-from-another-ref-ish)
- [I made several commits on a single branch that should be on different branches](#i-made-several-commits-on-a-single-branch-that-should-be-on-different-branches) - [I made several commits on a single branch that should be on different branches](#i-made-several-commits-on-a-single-branch-that-should-be-on-different-branches)
@ -297,6 +297,7 @@ If you want to see a file at a specific commit, you can also do this (where `<co
$ git show <commitid>:filename $ git show <commitid>:filename
``` ```
<a name="wrong-thing-in-commit-message"></a>
### I wrote the wrong thing in a commit message ### I wrote the wrong thing in a commit message
If you wrote the wrong thing and the commit has not yet been pushed, you can do the following to change the commit message without changing the changes in the commit: If you wrote the wrong thing and the commit has not yet been pushed, you can do the following to change the commit message without changing the changes in the commit:
@ -328,8 +329,18 @@ An alternative is to correctly configure your author settings in `git config --g
$ git commit --amend --reset-author --no-edit $ git commit --amend --reset-author --no-edit
``` ```
If you need to change for multiple commits, you can use
```sh
$ git -c rebase.instructionFormat='%s%nexec GIT_COMMITTER_DATE="%cD" GIT_AUTHOR_DATE="%aD" git commit --amend --no-edit --reset-author' rebase -r <commit>
```
`<commit>` is a commit before all your bad commits. If you need to change all of history in the current branch including the root of the branch, put `--root` there instead.
If you need to change all of history, see the man page for `git filter-branch`. If you need to change all of history, see the man page for `git filter-branch`.
Note this will change the history and a force push is required.
### I want to remove a file from the previous commit ### I want to remove a file from the previous commit
In order to remove changes for a file from the previous commit, do the following: In order to remove changes for a file from the previous commit, do the following:
@ -431,7 +442,7 @@ $ git push --force-with-lease [remote] [branch]
Or do an [interactive rebase](#interactive-rebase) and remove the line(s) corresponding to commit(s) you want to see removed. Or do an [interactive rebase](#interactive-rebase) and remove the line(s) corresponding to commit(s) you want to see removed.
<a name="#force-push"></a> <a name="force-push"></a>
### I tried to push my amended commit to a remote, but I got an error message ### I tried to push my amended commit to a remote, but I got an error message
```sh ```sh
@ -454,7 +465,7 @@ In general, **avoid force pushing**. It is best to create and push a new commit
If you are *absolutely* sure that nobody is working on the same branch or you want to update the tip of the branch *unconditionally*, you can use `--force` (`-f`), but this should be avoided in general. If you are *absolutely* sure that nobody is working on the same branch or you want to update the tip of the branch *unconditionally*, you can use `--force` (`-f`), but this should be avoided in general.
<a href="undo-git-reset-hard"></a> <a name="undo-git-reset-hard"></a>
### I accidentally did a hard reset, and I want my changes back ### I accidentally did a hard reset, and I want my changes back
If you accidentally do `git reset --hard`, you can normally still get your commit back, as git keeps a log of everything for a few days. If you accidentally do `git reset --hard`, you can normally still get your commit back, as git keeps a log of everything for a few days.
@ -473,7 +484,7 @@ You'll see a list of your past commits, and a commit for the reset. Choose the S
And you should be good to go. And you should be good to go.
<a href="undo-a-commit-merge"></a> <a name="undo-a-commit-merge"></a>
### I accidentally committed and pushed a merge ### I accidentally committed and pushed a merge
If you accidentally merged a feature branch to the main development branch before it was ready to be merged, you can still undo the merge. But there's a catch: A merge commit has more than one parent (usually two). If you accidentally merged a feature branch to the main development branch before it was ready to be merged, you can still undo the merge. But there's a catch: A merge commit has more than one parent (usually two).
@ -486,7 +497,7 @@ where the -m 1 option says to select parent number 1 (the branch into which the
Note: the parent number is not a commit identifier. Rather, a merge commit has a line `Merge: 8e2ce2d 86ac2e7`. The parent number is the 1-based index of the desired parent on this line, the first identifier is number 1, the second is number 2, and so on. Note: the parent number is not a commit identifier. Rather, a merge commit has a line `Merge: 8e2ce2d 86ac2e7`. The parent number is the 1-based index of the desired parent on this line, the first identifier is number 1, the second is number 2, and so on.
<a href="undo-sensitive-commit-push"></a> <a name="undo-sensitive-commit-push"></a>
### I accidentally committed and pushed files containing sensitive data ### I accidentally committed and pushed files containing sensitive data
If you accidentally pushed files containing sensitive, or private data (passwords, keys, etc.), you can amend the previous commit. Keep in mind that once you have pushed a commit, you should consider any data it contains to be compromised. These steps can remove the sensitive data from your public repo or your local copy, but you **cannot** remove the sensitive data from other people's pulled copies. If you committed a password, **change it immediately**. If you committed a key, **re-generate it immediately**. Amending the pushed commit is not enough, since anyone could have pulled the original commit containing your sensitive data in the meantime. If you accidentally pushed files containing sensitive, or private data (passwords, keys, etc.), you can amend the previous commit. Keep in mind that once you have pushed a commit, you should consider any data it contains to be compromised. These steps can remove the sensitive data from your public repo or your local copy, but you **cannot** remove the sensitive data from other people's pulled copies. If you committed a password, **change it immediately**. If you committed a key, **re-generate it immediately**. Amending the pushed commit is not enough, since anyone could have pulled the original commit containing your sensitive data in the meantime.
@ -518,10 +529,10 @@ If you want to completely remove an entire file (and not keep it locally), then
If you have made other commits in the meantime (i.e. the sensitive data is in a commit before the previous commit), you will have to rebase. If you have made other commits in the meantime (i.e. the sensitive data is in a commit before the previous commit), you will have to rebase.
<a href="#i-want-to-remove-a-large-file-from-ever-existing-in-repo-history"></a> <a name="remove-large-file-in-repo-history"></a>
### I want to remove a large file from ever existing in repo history ### I want to remove a large file from ever existing in repo history
If the file you want to delete is secret or sensitive, instead see [how to remove sensitive files](#i-accidentally-committed-and-pushed-files-containing-sensitive-data). If the file you want to delete is secret or sensitive, instead see [how to remove sensitive files](#undo-sensitive-commit-push).
Even if you delete a large or unwanted file in a recent commit, it still exists in git history, in your repo's `.git` folder, and will make `git clone` download unneeded files. Even if you delete a large or unwanted file in a recent commit, it still exists in git history, in your repo's `.git` folder, and will make `git clone` download unneeded files.
@ -592,7 +603,7 @@ If this does not work, you will need to manually push the repo history in chunks
``` ```
Once the push operation succeeds the first time, decrease `<number>` gradually until a conventional `git push` succeeds. Once the push operation succeeds the first time, decrease `<number>` gradually until a conventional `git push` succeeds.
<a href="i-need-to-change-the-content-of-a-commit-which-is-not-my-last"></a> <a name="change-content-of-commit-not-my-last"></a>
### I need to change the content of a commit which is not my last ### I need to change the content of a commit which is not my last
Consider you created some (e.g. three) commits and later realize you missed doing something that belongs contextually into the first of those commits. This bothers you, because if you'd create a new commit containing those changes, you'd have a clean code base, but your commits weren't atomic (i.e. changes that belonged to each other weren't in the same commit). In such a situation you may want to change the commit where these changes belong to, include them and have the following commits unaltered. In such a case, `git rebase` might save you. Consider you created some (e.g. three) commits and later realize you missed doing something that belongs contextually into the first of those commits. This bothers you, because if you'd create a new commit containing those changes, you'd have a clean code base, but your commits weren't atomic (i.e. changes that belonged to each other weren't in the same commit). In such a situation you may want to change the commit where these changes belong to, include them and have the following commits unaltered. In such a case, `git rebase` might save you.
@ -625,7 +636,7 @@ This tells rebase that you want to edit your third last commit and keep the othe
(your-branch)$ git commit --amend (your-branch)$ git commit --amend
``` ```
which tells Git to recreate the commit, but to leave the commit message unedited. Having done that, the hard part is solved. which tells Git to recreate the commit. Also, Git will ask you to write a new commit message, using the original commit message as a starting point. Having done that, the hard part is solved.
```sh ```sh
(your-branch)$ git rebase --continue (your-branch)$ git rebase --continue
@ -635,8 +646,7 @@ will do the rest of the work for you.
## Staging ## Staging
<a href="#i-want-to-stage-all-tracked-files-and-leave-untracked-files"></a> <a name="stage-tracked-files-and-leave-untracked-files"></a>
### I want to stage all tracked files and leave untracked files ### I want to stage all tracked files and leave untracked files
```sh ```sh
@ -653,7 +663,7 @@ $ git add -u *.txt
$ git add -u src/ $ git add -u src/
``` ```
<a href="#i-need-to-add-staged-changes-to-the-previous-commit"></a> <a name="add-staged-changes-to-previous-commit"></a>
### I need to add staged changes to the previous commit ### I need to add staged changes to the previous commit
```sh ```sh
@ -684,17 +694,17 @@ $ git add -N filename.x
Then, you will need to use the `e` option to manually choose which lines to add. Running `git diff --cached` or Then, you will need to use the `e` option to manually choose which lines to add. Running `git diff --cached` or
`git diff --staged` will show you which lines you have staged compared to which are still saved locally. `git diff --staged` will show you which lines you have staged compared to which are still saved locally.
<a href="stage-in-two-commits"></a> <a name="stage-in-two-commits"></a>
### I want to add changes in one file to two different commits ### I want to add changes in one file to two different commits
`git add` will add the entire file to a commit. `git add -p` will allow to interactively select which changes you want to add. `git add` will add the entire file to a commit. `git add -p` will allow to interactively select which changes you want to add.
<a href="selective-unstage-edits"></a> <a name="selective-unstage-edits"></a>
### I staged too many edits, and I want to break them out into a separate commit ### I staged too many edits, and I want to break them out into a separate commit
`git reset -p` will open a patch mode reset dialog. This is similar to `git add -p`, except that selecting "yes" will unstage the change, removing it from the upcoming commit. `git reset -p` will open a patch mode reset dialog. This is similar to `git add -p`, except that selecting "yes" will unstage the change, removing it from the upcoming commit.
<a href="unstaging-edits-and-staging-the-unstaged"></a> <a name="unstaging-edits-and-staging-the-unstaged"></a>
### I want to stage my unstaged edits, and unstage my staged edits ### I want to stage my unstaged edits, and unstage my staged edits
In many cases, you should unstage all of your staged files and then pick the file you want and commit it. However, if you want to switch the staged and unstaged edits, you can create a temporary commit to store your staged files, stage your unstaged files and then stash them. Then, reset the temporary commit and pop your stash. In many cases, you should unstage all of your staged files and then pick the file you want and commit it. However, if you want to switch the staged and unstaged edits, you can create a temporary commit to store your staged files, stage your unstaged files and then stash them. Then, reset the temporary commit and pop your stash.
@ -710,25 +720,20 @@ $ git stash pop --index 0
NOTE 1: The reason to use `pop` here is want to keep idempotent as much as possible. NOTE 1: The reason to use `pop` here is want to keep idempotent as much as possible.
NOTE 2: Your staged files will be marked as unstaged if you don't use the `--index` flag. ([This link](https://stackoverflow.com/questions/31595873/git-stash-with-staged-files-does-stash-convert-staged-files-to-unstaged?answertab=active#tab-top) explains why.) NOTE 2: Your staged files will be marked as unstaged if you don't use the `--index` flag. ([This link](https://stackoverflow.com/questions/31595873/git-stash-with-staged-files-does-stash-convert-staged-files-to-unstaged?answertab=active#tab-top) explains why.)
## Unstaged Edits <a name="unstage-specific-staged-file"></a>
### I want to unstage a specific staged file
<a href="move-unstaged-edits-to-new-branch"></a> Sometimes we have one or more files that accidentally ended up being staged, and these files have not been committed before. To unstage them:
### I want to move my unstaged edits to a new branch
```sh ```sh
$ git checkout -b my-branch $ git reset -- <filename>
``` ```
<a href="move-unstaged-edits-to-old-branch"></a> This results in unstaging the file and make it look like it's untracked.
### I want to move my unstaged edits to a different, existing branch
```sh ## Discarding changes
$ git stash
$ git checkout my-branch
$ git stash pop
```
<a href="i-want-to-discard-my-local-uncommitted-changes"></a> <a name="discard-local-uncommitted-changes"></a>
### I want to discard my local uncommitted changes (staged and unstaged) ### I want to discard my local uncommitted changes (staged and unstaged)
If you want to discard all your local staged and unstaged changes, you can do this: If you want to discard all your local staged and unstaged changes, you can do this:
@ -820,7 +825,7 @@ When you want to get rid of all of your unstaged local uncommitted changes
```sh ```sh
$ git checkout . $ git checkout .
``` ```
<a href="i-want-to-discard-all-my-untracked-files"></a> <a name="discard-all-untracked-files"></a>
### I want to discard all of my untracked files ### I want to discard all of my untracked files
When you want to get rid of all of your untracked files When you want to get rid of all of your untracked files
@ -829,17 +834,6 @@ When you want to get rid of all of your untracked files
$ git clean -f $ git clean -f
``` ```
<a href="I-want-to-unstage-specific-staged-file"></a>
### I want to unstage a specific staged file
Sometimes we have one or more files that accidentally ended up being staged, and these files have not been committed before. To unstage them:
```sh
$ git reset -- <filename>
```
This results in unstaging the file and make it look like it's untracked.
## Branches ## Branches
### I want to list all branches ### I want to list all branches
@ -887,7 +881,7 @@ $ git reset --hard c5bc55a
Done. Done.
<a href="discard-local-commits"></a> <a name="discard-local-commits"></a>
### I want to discard local commits so my branch is the same as one on the server ### I want to discard local commits so my branch is the same as one on the server
Confirm that you haven't pushed your changes to the server. Confirm that you haven't pushed your changes to the server.
@ -908,6 +902,22 @@ One way of resetting branch `my-branch` to match `origin/my-branch` (to have the
(my-branch)$ git reset --hard origin/my-branch (my-branch)$ git reset --hard origin/my-branch
``` ```
<a name="move-unstaged-edits-to-new-branch"></a>
### I want to move my unstaged edits to a new branch
```sh
$ git checkout -b my-branch
```
<a name="move-unstaged-edits-to-old-branch"></a>
### I want to move my unstaged edits to a different, existing branch
```sh
$ git stash
$ git checkout my-branch
$ git stash pop
```
<a name="commit-wrong-branch"></a> <a name="commit-wrong-branch"></a>
### I committed to main instead of a new branch ### I committed to main instead of a new branch
@ -1055,7 +1065,7 @@ $ git fetch -p upstream
where, `upstream` is the remote you want to fetch from. where, `upstream` is the remote you want to fetch from.
<a name='restore-a-deleted-branch'></a> <a name="restore-a-deleted-branch"></a>
### I accidentally deleted my branch ### I accidentally deleted my branch
If you're regularly pushing to remote, you should be safe most of the time. But still sometimes you may end up deleting your branches. Let's say we create a branch and create a new file: If you're regularly pushing to remote, you should be safe most of the time. But still sometimes you may end up deleting your branches. Let's say we create a branch and create a new file:
@ -1179,7 +1189,7 @@ To delete the `old-name` remote branch and push the `new-name` local branch:
(main)$ git push origin :old_name new_name (main)$ git push origin :old_name new_name
``` ```
<a name="i-want-to-checkout-to-a-remote-branch-that-someone-else-is-working-on"></a> <a name="working-on-checkout-remote-branch"></a>
### I want to checkout to a remote branch that someone else is working on ### I want to checkout to a remote branch that someone else is working on
First, fetch all branches from remote: First, fetch all branches from remote:
@ -1218,7 +1228,7 @@ With the `upstream` mode and the `simple` (default in Git 2.0) mode of the `push
$ git push $ git push
``` ```
The behavior of the other modes of `git push` is described in the [doc of `push.default`](https://git-scm.com/docs/git-config#git-config-pushdefault). The behavior of the other modes of `git push` is described in the [doc of `push.default`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushdefault).
### I want to set a remote branch as the upstream for a local branch ### I want to set a remote branch as the upstream for a local branch
@ -1236,7 +1246,7 @@ To set the upstream remote branch for another local branch:
$ git branch -u [remotename]/[branch] [local-branch] $ git branch -u [remotename]/[branch] [local-branch]
``` ```
<a name="i-want-to-set-my-HEAD-to-track-the-default-remote-branch"></a> <a name="head-to-track-remote-branch"></a>
### I want to set my HEAD to track the default remote branch ### I want to set my HEAD to track the default remote branch
By checking your remote branches, you can see which remote branch your HEAD is tracking. In some cases, this is not the desired branch. By checking your remote branches, you can see which remote branch your HEAD is tracking. In some cases, this is not the desired branch.
@ -1264,7 +1274,7 @@ You've made uncommitted changes and realise you're on the wrong branch. Stash ch
(correct_branch)$ git stash apply (correct_branch)$ git stash apply
``` ```
<a name="i-want-to-split-a-branch-into-two"></a> <a name="split-branch-into-two"></a>
### I want to split a branch into two ### I want to split a branch into two
You've made a lot of commits on a branch and now want to separate it into two, ending with a branch up to an earlier commit and another with all the changes. You've made a lot of commits on a branch and now want to separate it into two, ending with a branch up to an earlier commit and another with all the changes.
@ -1506,7 +1516,7 @@ If you want to keep one branch's version of the code, you can use `--ours` or `-
``` ```
- When *merging*, use `--ours` to keep changes from the local branch, or `--theirs` to keep changes from the other branch. - When *merging*, use `--ours` to keep changes from the local branch, or `--theirs` to keep changes from the other branch.
- When *rebasing*, use `--theirs` to keep changes from the local branch, or `--ours` to keep changes from the other branch. For an explanation of this swap, see [this note in the Git documentation](https://git-scm.com/docs/git-rebase#git-rebase---merge). - When *rebasing*, use `--theirs` to keep changes from the local branch, or `--ours` to keep changes from the other branch. For an explanation of this swap, see [this note in the Git documentation](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---merge).
If the merges are more complicated, you can use a visual diff editor: If the merges are more complicated, you can use a visual diff editor:
@ -1624,7 +1634,7 @@ Commons parameters:
* `--reverse` prints in reverse order, it means that will show the first commit that made the change. * `--reverse` prints in reverse order, it means that will show the first commit that made the change.
<a name="i-want-to-find-by-author-committer"></a> <a name="find-by-committer"></a>
### I want to find by author/committer ### I want to find by author/committer
To find all commits by author/committer you can use: To find all commits by author/committer you can use:
@ -1656,7 +1666,7 @@ While using wildcards, it's useful to inform `--name-status` to see the list of
$ git log --name-status -- **/*.js $ git log --name-status -- **/*.js
``` ```
<a name="#i-want-to-view-the-commit-history-for-a-specific-function"></a> <a name="view-commit-history-for-specific-function"></a>
### I want to view the commit history for a specific function ### I want to view the commit history for a specific function
To trace the evolution of a single function you can use: To trace the evolution of a single function you can use:
@ -1787,7 +1797,7 @@ $ git push origin refs/tags/<tag-name>
## Tracking Files ## Tracking Files
<a href="i-want-to-change-a-file-names-capitalization-without-changing-the-contents-of-the-file"></a> <a name="change-file-name-capitalization-without-changing-contents"></a>
### I want to change a file name's capitalization, without changing the contents of the file ### I want to change a file name's capitalization, without changing the contents of the file
```sh ```sh
@ -1801,7 +1811,7 @@ $ git push origin refs/tags/<tag-name>
(main)$ git reset --hard origin/main (main)$ git reset --hard origin/main
``` ```
<a href="remove-from-git"></a> <a name="remove-from-git"></a>
### I want to remove a file from Git but keep the file ### I want to remove a file from Git but keep the file
```sh ```sh
@ -2073,13 +2083,14 @@ function Squash-Commits {
* [19 Git Tips For Everyday Use](https://www.alexkras.com/19-git-tips-for-everyday-use) - A list of useful Git one liners * [19 Git Tips For Everyday Use](https://www.alexkras.com/19-git-tips-for-everyday-use) - A list of useful Git one liners
* [Atlassian's Git tutorial](https://www.atlassian.com/git/tutorials) Get Git right with tutorials from beginner to advanced. * [Atlassian's Git tutorial](https://www.atlassian.com/git/tutorials) Get Git right with tutorials from beginner to advanced.
* [Learn Git branching](https://learngitbranching.js.org/) An interactive web based branching/merging/rebasing tutorial
* [Getting solid at Git rebase vs. merge](https://medium.com/@porteneuve/getting-solid-at-git-rebase-vs-merge-4fa1a48c53aa) * [Getting solid at Git rebase vs. merge](https://medium.com/@porteneuve/getting-solid-at-git-rebase-vs-merge-4fa1a48c53aa)
* [Git and GitHub Cartoons](https://allisonhorst.com/git-github) Cartoons by Allison Horst that showcase how to use Git.
* [Git Commands and Best Practices Cheat Sheet](https://zeroturnaround.com/rebellabs/git-commands-and-best-practices-cheat-sheet) - A Git cheat sheet in a blog post with more explanations * [Git Commands and Best Practices Cheat Sheet](https://zeroturnaround.com/rebellabs/git-commands-and-best-practices-cheat-sheet) - A Git cheat sheet in a blog post with more explanations
* [Git from the inside out](https://codewords.recurse.com/issues/two/git-from-the-inside-out) - A tutorial that dives into Git's internals * [Git from the inside out](https://codewords.recurse.com/issues/two/git-from-the-inside-out) - A tutorial that dives into Git's internals
* [git-workflow](https://github.com/asmeurer/git-workflow) - [Aaron Meurer](https://github.com/asmeurer)'s howto on using Git to contribute to open source repositories * [git-workflow](https://github.com/asmeurer/git-workflow) - [Aaron Meurer](https://github.com/asmeurer)'s howto on using Git to contribute to open source repositories
* [GitHub as a workflow](https://hugogiraudel.com/2015/08/13/github-as-a-workflow/) - An interesting take on using GitHub as a workflow, particularly with empty PRs * [GitHub as a workflow](https://hugogiraudel.com/2015/08/13/github-as-a-workflow/) - An interesting take on using GitHub as a workflow, particularly with empty PRs
* [Githug](https://github.com/Gazler/githug) - A game to learn more common Git workflows * [Githug](https://github.com/Gazler/githug) - A game to learn more common Git workflows
* [Learn Git branching](https://learngitbranching.js.org/) An interactive web based branching/merging/rebasing tutorial
* [learnGitBranching](https://github.com/pcottle/learnGitBranching) - An interactive git visualization to challenge and educate! * [learnGitBranching](https://github.com/pcottle/learnGitBranching) - An interactive git visualization to challenge and educate!
## Scripts and Tools ## Scripts and Tools

View File

@ -1065,7 +1065,7 @@ Si deseas conservar la versión del código de una rama, puedes usar `--us` o` -
``` ```
- Cuando haces *merge*, usa `--ours` para mantener los cambios de la rama local, o` --theirs` para mantener los cambios de la otra rama. - Cuando haces *merge*, usa `--ours` para mantener los cambios de la rama local, o` --theirs` para mantener los cambios de la otra rama.
- Cuando haces *rebase*, usa `--theirs` para mantener los cambios de la rama local, o` --ours` para mantener los cambios de la otra rama. Para obtener una explicación de este intercambio, consulte [esta nota en la documentación de Git] (https://git-scm.com/docs/git-rebase#git-rebase---merge). - Cuando haces *rebase*, usa `--theirs` para mantener los cambios de la rama local, o` --ours` para mantener los cambios de la otra rama. Para obtener una explicación de este intercambio, consulte [esta nota en la documentación de Git] (https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---merge).
Si las fusiones son más complicadas, puede usar un editor visual diff: Si las fusiones son más complicadas, puede usar un editor visual diff:

View File

@ -174,6 +174,7 @@ Si vous voulez voir un fichier à un commit spécifique, vous pouvez aussi faire
$ git show <commitid>:nomdufichier $ git show <commitid>:nomdufichier
``` ```
<a name="wrong-thing-in-commit-message"></a>
### J'ai commis une erreur dans un message de commit ### J'ai commis une erreur dans un message de commit
Si vous vous êtes trompé·e et que le commit n'a pas encore été poussé, vous pouvez appliquer la commande suivante afin de changer le message du commit sans affecter les changements de ce même commit : Si vous vous êtes trompé·e et que le commit n'a pas encore été poussé, vous pouvez appliquer la commande suivante afin de changer le message du commit sans affecter les changements de ce même commit :
@ -256,7 +257,7 @@ $ git push --force-with-lease [remote] [branche]
Ou faites un [rebase interactif](#interactive-rebase) et retirez les lignes correspondantes au(x) commit(s) que vous souhaitez supprimer. Ou faites un [rebase interactif](#interactive-rebase) et retirez les lignes correspondantes au(x) commit(s) que vous souhaitez supprimer.
<a name="#force-push"></a> <a name="force-push"></a>
### J'ai essayé de pousser un commit modifié vers le dépôt distant, mais j'ai eu un message d'erreur ### J'ai essayé de pousser un commit modifié vers le dépôt distant, mais j'ai eu un message d'erreur
```sh ```sh
@ -279,7 +280,7 @@ En règle générale, **évitez de pousser de force**. Il est préférable de cr
Si vous êtes *absolument* sûr·e que personne n'est en train de travailler sur la même branche que vous ou que vous souhaitez mettre à jour la branche de manière *inconditionnelle*, vous pouvez utiliser `--force` (`-f`), mais cela devrait être évité en général. Si vous êtes *absolument* sûr·e que personne n'est en train de travailler sur la même branche que vous ou que vous souhaitez mettre à jour la branche de manière *inconditionnelle*, vous pouvez utiliser `--force` (`-f`), mais cela devrait être évité en général.
<a href="undo-git-reset-hard"></a> <a name="undo-git-reset-hard"></a>
### J'ai fait un hard reset par accident, et je veux retrouver mes changements ### J'ai fait un hard reset par accident, et je veux retrouver mes changements
Si vous avez accidentellement fait un `git reset --hard`, vous pouvez normalement retrouver votre commit, car Git garde un log de tout ce que vous faites pendant quelques jours. Si vous avez accidentellement fait un `git reset --hard`, vous pouvez normalement retrouver votre commit, car Git garde un log de tout ce que vous faites pendant quelques jours.
@ -298,7 +299,7 @@ Vous verrez une liste de vos précédents commits, et un commit pour la réiniti
Et cela devrait faire l'affaire. Et cela devrait faire l'affaire.
<a href="undo-a-commit-merge"></a> <a name="undo-a-commit-merge"></a>
### J'ai commité et poussé une fusion par accident ### J'ai commité et poussé une fusion par accident
Si vous avez accidentellement fusionné une branche d'une fonctionnalité avec la branche de développement principale avant qu'elle ne soit prête à être fusionnée, vous pouvez toujours annuler cette fusion. Mais il y a un piège : un commit de fusion a plus d'un parent (en général deux). Si vous avez accidentellement fusionné une branche d'une fonctionnalité avec la branche de développement principale avant qu'elle ne soit prête à être fusionnée, vous pouvez toujours annuler cette fusion. Mais il y a un piège : un commit de fusion a plus d'un parent (en général deux).
@ -312,7 +313,7 @@ où l'option `-m 1` demande de sélectionner le parent numéro 1 (la branche ver
À noter : le numéro du parent n'est pas un identifiant de commit. Un commit de fusion ressemble plus à `Merge: 8e2ce2d 86ac2e7`. Le numéro du parent est l'index basé sur 1 du parent souhaité sur cette ligne, le premier identifiant est le numéro 1, le second le numéro 2, et ainsi de suite. À noter : le numéro du parent n'est pas un identifiant de commit. Un commit de fusion ressemble plus à `Merge: 8e2ce2d 86ac2e7`. Le numéro du parent est l'index basé sur 1 du parent souhaité sur cette ligne, le premier identifiant est le numéro 1, le second le numéro 2, et ainsi de suite.
<a href="undo-sensitive-commit-push"></a> <a name="undo-sensitive-commit-push"></a>
### J'ai commité et poussé des fichiers contenant des données sensibles par accident ### J'ai commité et poussé des fichiers contenant des données sensibles par accident
Si vous avez accidentellement poussé des fichiers contenant des données sensibles (mots de passe, clés, etc.), vous pouvez modifier le commit précédent. Gardez toutefois à l'esprit qu'une fois que vous avez poussé un commit, vous devez considérer n'importe quelle donnée qu'il contient comme étant compromise. Ces étapes peuvent supprimer les données sensibles de votre dépôt public ou de votre copie locale, mais vous ne **pouvez pas** supprimer les données sensibles des copies clonées par d'autres personnes. Si vous avez commité un mot de passe, **changez-le immédiatement**. Si vous avez commité une clé, **révoquez-la et régénérez-la immédiatement**. Modifier le commit poussé n'est pas suffisant, étant donné que n'importe qui aurait pu extraire le commit original contenant vos données sensibles pendant ce temps. Si vous avez accidentellement poussé des fichiers contenant des données sensibles (mots de passe, clés, etc.), vous pouvez modifier le commit précédent. Gardez toutefois à l'esprit qu'une fois que vous avez poussé un commit, vous devez considérer n'importe quelle donnée qu'il contient comme étant compromise. Ces étapes peuvent supprimer les données sensibles de votre dépôt public ou de votre copie locale, mais vous ne **pouvez pas** supprimer les données sensibles des copies clonées par d'autres personnes. Si vous avez commité un mot de passe, **changez-le immédiatement**. Si vous avez commité une clé, **révoquez-la et régénérez-la immédiatement**. Modifier le commit poussé n'est pas suffisant, étant donné que n'importe qui aurait pu extraire le commit original contenant vos données sensibles pendant ce temps.
@ -345,7 +346,7 @@ Si vous avez créé d'autres commits pendant ce temps (c'est à dire que les don
## Indexation ## Indexation
<a href="#i-need-to-add-staged-changes-to-the-previous-commit"></a> <a name="add-staged-changes-to-previous-commit"></a>
### J'ai besoin d'ajouter des modifications indexées sur le commit précédent ### J'ai besoin d'ajouter des modifications indexées sur le commit précédent
```sh ```sh
@ -376,12 +377,12 @@ $ git add -N nomdufichier.x
Ensuite, vous devrez utiliser l'option `e` afin de choisir manuellement quelles lignes ajouter. Lancer `git diff --cached` ou `git diff --staged` vous montrera quelles lignes vous avez indexées comparées à celles qui sont toujours sauvegardées en local. Ensuite, vous devrez utiliser l'option `e` afin de choisir manuellement quelles lignes ajouter. Lancer `git diff --cached` ou `git diff --staged` vous montrera quelles lignes vous avez indexées comparées à celles qui sont toujours sauvegardées en local.
<a href="stage-in-two-commits"></a> <a name="stage-in-two-commits"></a>
### Je veux ajouter les changements d'un fichier dans deux commits différents ### Je veux ajouter les changements d'un fichier dans deux commits différents
`git add` ajoutera le fichier entier à un commit. `git add -p` vous permettra de sélectionner interactivement quels changements vous souhaitez ajouter. `git add` ajoutera le fichier entier à un commit. `git add -p` vous permettra de sélectionner interactivement quels changements vous souhaitez ajouter.
<a href="unstaging-edits-and-staging-the-unstaged"></a> <a name="unstaging-edits-and-staging-the-unstaged"></a>
### Je veux indexer mes modifications indexées, et désindexer mes modifications indexées ### Je veux indexer mes modifications indexées, et désindexer mes modifications indexées
Cela est délicat. La meilleure chose que nous pouvons vous conseiller est que vous devriez remiser vos modifications non indexées, puis utiliser `git reset`. Après cela, utilisez `pop` pour déremiser vos modifications, puis ajoutez-les : Cela est délicat. La meilleure chose que nous pouvons vous conseiller est que vous devriez remiser vos modifications non indexées, puis utiliser `git reset`. Après cela, utilisez `pop` pour déremiser vos modifications, puis ajoutez-les :
@ -395,14 +396,14 @@ $ git add -A
## Modifications non indexées ## Modifications non indexées
<a href="move-unstaged-edits-to-new-branch"></a> <a name="move-unstaged-edits-to-new-branch"></a>
### Je veux déplacer mes modifications non indexées vers une nouvelle branche ### Je veux déplacer mes modifications non indexées vers une nouvelle branche
```sh ```sh
$ git checkout -b ma-branche $ git checkout -b ma-branche
``` ```
<a href="move-unstaged-edits-to-old-branch"></a> <a name="move-unstaged-edits-to-old-branch"></a>
### Je veux déplacer mes modifications non indexées vers une branche différente existante ### Je veux déplacer mes modifications non indexées vers une branche différente existante
```sh ```sh
@ -411,7 +412,7 @@ $ git checkout ma-branche
$ git stash pop $ git stash pop
``` ```
<a href="i-want-to-discard-my-local-uncommitted-changes"></a> <a name="discard-local-uncommitted-changes"></a>
### Je veux me débarrasser de mes modifications locales non commitées (indexées et non-indexées) ### Je veux me débarrasser de mes modifications locales non commitées (indexées et non-indexées)
Si vous voulez vous débarrasser de toutes vos modifications locales indexées et non-indexées, vous pouvez faire ceci : Si vous voulez vous débarrasser de toutes vos modifications locales indexées et non-indexées, vous pouvez faire ceci :
@ -501,7 +502,7 @@ Quand vous souhaitez vous débarrasser de toutes vos modifications locales non c
```sh ```sh
$ git checkout . $ git checkout .
``` ```
<a href="i-want-to-discard-all-my-untracked-files"></a> <a name="discard-all-untracked-files"></a>
### Je veux me débarrasser de tous mes fichiers non suivis ### Je veux me débarrasser de tous mes fichiers non suivis
Quand vous souhaitez vous débarrasser de tous vos fichiers non suivis : Quand vous souhaitez vous débarrasser de tous vos fichiers non suivis :
@ -510,7 +511,7 @@ Quand vous souhaitez vous débarrasser de tous vos fichiers non suivis :
$ git clean -f $ git clean -f
``` ```
<a href="I-want-to-unstage-specific-staged-file"></a> <a name="unstage-specific-staged-file"></a>
### Je veux désindexer un fichier indexé spécifique ### Je veux désindexer un fichier indexé spécifique
Il arrive parfois que nous ayons un ou plusieurs fichiers qui ont été indexés par accident. Et ces fichiers n'ont pas été commités auparavant. Pour les désindexer : Il arrive parfois que nous ayons un ou plusieurs fichiers qui ont été indexés par accident. Et ces fichiers n'ont pas été commités auparavant. Pour les désindexer :
@ -568,7 +569,7 @@ $ git reset --hard c5bc55a
Et voilà. Et voilà.
<a href="discard-local-commits"></a> <a name="discard-local-commits"></a>
### Je veux supprimer mes commits locaux afin que ma branche soit pareille à celle sur le serveur ### Je veux supprimer mes commits locaux afin que ma branche soit pareille à celle sur le serveur
Assurez-vous que vous n'avez pas poussé vos modifications sur le serveur. Assurez-vous que vous n'avez pas poussé vos modifications sur le serveur.
@ -735,7 +736,7 @@ $ git fetch -p upstream
`upstream` est le dépôt distant depuis lequel vous voulez mettre à jour. `upstream` est le dépôt distant depuis lequel vous voulez mettre à jour.
<a name='restore-a-deleted-branch'></a> <a name="restore-a-deleted-branch"></a>
### J'ai supprimé ma branche par accident ### J'ai supprimé ma branche par accident
Si vous poussez régulièrement sur la branche distante, vous devriez ne pas avoir de problème la plupart du temps. Mais il arrive parfois que vous finissez par supprimer vos branches. Admettons que nous créons une nouvelle branche avec un nouveau fichier : Si vous poussez régulièrement sur la branche distante, vous devriez ne pas avoir de problème la plupart du temps. Mais il arrive parfois que vous finissez par supprimer vos branches. Admettons que nous créons une nouvelle branche avec un nouveau fichier :
@ -853,7 +854,7 @@ Pour renommer une autre branche (locale) :
(main)$ git branch -m ancien-nom nouveau-nom (main)$ git branch -m ancien-nom nouveau-nom
``` ```
<a name="i-want-to-checkout-to-a-remote-branch-that-someone-else-is-working-on"></a> <a name="working-on-checkout-remote-branch"></a>
### Je veux me déplacer sur une branche distante sur laquelle quelqu'un est en train de travailler ### Je veux me déplacer sur une branche distante sur laquelle quelqu'un est en train de travailler
Pour commencer, récupérez toutes les branches depuis le dépôt distant : Pour commencer, récupérez toutes les branches depuis le dépôt distant :
@ -892,7 +893,7 @@ Avec le mode `upstream` et le mode `simple` (défaut dans Git 2.0) de la configu
$ git push $ git push
``` ```
Le comportement des autres modes de `git push` est détaillé dans la [documentation de `push.default`](https://git-scm.com/docs/git-config#git-config-pushdefault). Le comportement des autres modes de `git push` est détaillé dans la [documentation de `push.default`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushdefault).
### Je veux configurer une branche distante en tant qu'upstream pour une branche locale ### Je veux configurer une branche distante en tant qu'upstream pour une branche locale
@ -910,7 +911,7 @@ Pour configurer la branche distante en tant qu'upstream pour une autre branche l
$ git branch -u [nomduremote]/[branche] [branche-locale] $ git branch -u [nomduremote]/[branche] [branche-locale]
``` ```
<a name="i-want-to-set-my-HEAD-to-track-the-default-remote-branch"></a> <a name="head-to-track-remote-branch"></a>
### Je veux configurer mon HEAD pour suivre la branche distante par défaut ### Je veux configurer mon HEAD pour suivre la branche distante par défaut
En vérifiant vos branches distantes, vous pouvez voir lesquelles d'entre-elles sont suivies par HEAD. Dans certains cas, ce n'est pas la branche désirée. En vérifiant vos branches distantes, vous pouvez voir lesquelles d'entre-elles sont suivies par HEAD. Dans certains cas, ce n'est pas la branche désirée.
@ -1165,7 +1166,7 @@ Si vous voulez garder la version du code d'une des branches, vous pouvez utilise
``` ```
- Quand vous *fusionnez*, utilisez `--ours` pour garder les modifications de la branche locale, ou `--theirs` pour garder les modifications de l'autre branche. - Quand vous *fusionnez*, utilisez `--ours` pour garder les modifications de la branche locale, ou `--theirs` pour garder les modifications de l'autre branche.
- Quand vous *rebasez*, utilisez `--theirs` pour garder les modifications de la branche locale, ou `--ours` pour garder les modifications de l'autre branche. Pour des explications concernant cet échange, consultez [cette note dans la documentation de Git](https://git-scm.com/docs/git-rebase#git-rebase---merge). - Quand vous *rebasez*, utilisez `--theirs` pour garder les modifications de la branche locale, ou `--ours` pour garder les modifications de l'autre branche. Pour des explications concernant cet échange, consultez [cette note dans la documentation de Git](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---merge).
Si les fusions sont plus complexes, vous pouvez utiliser un éditeur de diff visuel : Si les fusions sont plus complexes, vous pouvez utiliser un éditeur de diff visuel :
@ -1261,7 +1262,7 @@ Paramètres communs :
* `--reverse` retourne les résultats dans l'ordre inverse, c'est à dire que la commande affichera le premier commit qui a fait la modification. * `--reverse` retourne les résultats dans l'ordre inverse, c'est à dire que la commande affichera le premier commit qui a fait la modification.
<a name="i-want-to-find-by-author-committer"></a> <a name="find-by-committer"></a>
### Je veux rechercher par auteur·trice/validateur·trice ### Je veux rechercher par auteur·trice/validateur·trice
Pour rechercher des commits par auteur·trice/validateur·trice, vous pouvez utiliser : Pour rechercher des commits par auteur·trice/validateur·trice, vous pouvez utiliser :
@ -1408,7 +1409,7 @@ $ git push origin refs/tags/<nom-du-tag>
## Suivre des fichiers ## Suivre des fichiers
<a href="i-want-to-change-a-file-names-capitalization-without-changing-the-contents-of-the-file"></a> <a name="change-file-name-capitalization-without-changing-contents"></a>
### Je veux changer la capitalisation du nom d'un fichier, sans changer son contenu ### Je veux changer la capitalisation du nom d'un fichier, sans changer son contenu
```sh ```sh
@ -1422,7 +1423,7 @@ $ git push origin refs/tags/<nom-du-tag>
(main)$ git reset --hard origin/main (main)$ git reset --hard origin/main
``` ```
<a href="remove-from-git"></a> <a name="remove-from-git"></a>
### Je veux retirer un fichier de Git mais garder le fichier ### Je veux retirer un fichier de Git mais garder le fichier
```sh ```sh

View File

@ -37,7 +37,7 @@ Git のバージョンアップについては [Git のウェブサイト](https
- [コミットの編集](#%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%AE%E7%B7%A8%E9%9B%86) - [コミットの編集](#%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%AE%E7%B7%A8%E9%9B%86)
- [何をコミットしたかわからなくなった](#%E4%BD%95%E3%82%92%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%97%E3%81%9F%E3%81%8B%E3%82%8F%E3%81%8B%E3%82%89%E3%81%AA%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F) - [何をコミットしたかわからなくなった](#%E4%BD%95%E3%82%92%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%97%E3%81%9F%E3%81%8B%E3%82%8F%E3%81%8B%E3%82%89%E3%81%AA%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F)
- [コミットメッセージに間違った内容を書いてしまった](#%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%81%AB%E9%96%93%E9%81%95%E3%81%A3%E3%81%9F%E5%86%85%E5%AE%B9%E3%82%92%E6%9B%B8%E3%81%84%E3%81%A6%E3%81%97%E3%81%BE%E3%81%A3%E3%81%9F) - [コミットメッセージに間違った内容を書いてしまった](#%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%81%AB%E9%96%93%E9%81%95%E3%81%A3%E3%81%9F%E5%86%85%E5%AE%B9%E3%82%92%E6%9B%B8%E3%81%84%E3%81%A6%E3%81%97%E3%81%BE%E3%81%A3%E3%81%9F)
- [間違った名前・メールアドレスでコミットしてしまった](#%E9%96%93%E9%81%95%E3%81%A3%E3%81%9F%E5%90%8D%E5%89%8D%E3%83%BB%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%A7%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%97%E3%81%A6%E3%81%97%E3%81%BE%E3%81%A3%E3%81%9F) - [間違った名前・メールアドレスでコミットしてしまった](#%E9%96%93%E9%81%95%E3%81%A3%E3%81%9F%E5%90%8D%E5%89%8D%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%A7%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%97%E3%81%A6%E3%81%97%E3%81%BE%E3%81%A3%E3%81%9F)
- [直前のコミットからファイルを削除したい](#%E7%9B%B4%E5%89%8D%E3%81%AE%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%8B%E3%82%89%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%81%84) - [直前のコミットからファイルを削除したい](#%E7%9B%B4%E5%89%8D%E3%81%AE%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%8B%E3%82%89%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%81%84)
- [直前のコミットを削除したい](#%E7%9B%B4%E5%89%8D%E3%81%AE%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%82%92%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%81%84) - [直前のコミットを削除したい](#%E7%9B%B4%E5%89%8D%E3%81%AE%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%82%92%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%81%84)
- [特定のコミットを削除したい](#%E7%89%B9%E5%AE%9A%E3%81%AE%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%82%92%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%81%84) - [特定のコミットを削除したい](#%E7%89%B9%E5%AE%9A%E3%81%AE%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%82%92%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%81%84)
@ -299,6 +299,7 @@ $ git log -n1 -p
$ git show <commitid>:filename $ git show <commitid>:filename
``` ```
<a name="wrong-thing-in-commit-message"></a>
### コミットメッセージに間違った内容を書いてしまった ### コミットメッセージに間違った内容を書いてしまった
コミットメッセージに間違った内容を書いてしまったとします。 コミットメッセージに間違った内容を書いてしまったとします。
@ -390,7 +391,7 @@ $ git push --force-with-lease [remote] [branch]
あるいは、[対話的 rebase](#interactive-rebase) で削除したいコミットに対応する行を選択して削除します。 あるいは、[対話的 rebase](#interactive-rebase) で削除したいコミットに対応する行を選択して削除します。
<a name="#force-push"></a> <a name="force-push"></a>
### 修正したコミットをリモートにプッシュしようとしたら、エラーメッセージが出た ### 修正したコミットをリモートにプッシュしようとしたら、エラーメッセージが出た
```sh ```sh
@ -419,7 +420,7 @@ amend による修正は、rebase と同様に(後述)、**古いコミッ
他の誰も同じブランチで作業していないことが*絶対に*確実な場合、あるいはブランチの一部を*無条件で*更新したい場合は `--force` (`-f`) で行うことができますが、これは原則として避けるべきです。 他の誰も同じブランチで作業していないことが*絶対に*確実な場合、あるいはブランチの一部を*無条件で*更新したい場合は `--force` (`-f`) で行うことができますが、これは原則として避けるべきです。
<a href="undo-git-reset-hard"></a> <a name="undo-git-reset-hard"></a>
### 間違えて hard reset してしまい、元に戻したい ### 間違えて hard reset してしまい、元に戻したい
間違えて `git reset --hard` をしてしまっても、大抵はコミットを復元できます。 間違えて `git reset --hard` をしてしまっても、大抵はコミットを復元できます。
@ -441,7 +442,7 @@ Git は数日間のログを全て残してくれているからです。
これで大丈夫です。 これで大丈夫です。
<a href="undo-a-commit-merge"></a> <a name="undo-a-commit-merge"></a>
### 間違えてマージをコミットしてプッシュしてしまった ### 間違えてマージをコミットしてプッシュしてしまった
マージの準備ができていないフィーチャーブランチをメインのブランチにマージしてしまったときは、マージを取り消すことができます。 マージの準備ができていないフィーチャーブランチをメインのブランチにマージしてしまったときは、マージを取り消すことができます。
@ -459,7 +460,7 @@ Git は数日間のログを全て残してくれているからです。
マージコミットの行は `Merge: 8e2ce2d 86ac2e7` のようになっています。 マージコミットの行は `Merge: 8e2ce2d 86ac2e7` のようになっています。
親番号はこのコミットの親を指定する 1 から始まる番号で、最初の番号は 1 番、次は 2 番、のように振られます。 親番号はこのコミットの親を指定する 1 から始まる番号で、最初の番号は 1 番、次は 2 番、のように振られます。
<a href="undo-sensitive-commit-push"></a> <a name="undo-sensitive-commit-push"></a>
### 間違えて機密情報を含むファイルをコミットしプッシュしてしまった ### 間違えて機密情報を含むファイルをコミットしプッシュしてしまった
機密情報やプライベートな情報(パスワードやキー等)を含むデータを誤ってプッシュしてしまった場合、コミットを修正できます。 機密情報やプライベートな情報(パスワードやキー等)を含むデータを誤ってプッシュしてしまった場合、コミットを修正できます。
@ -499,10 +500,10 @@ echo sensitive_file >> .gitignore
すでに他のコミットをしてしまった場合(つまり、機密情報のコミットが直前のコミットよりも前である場合)は、リベースする必要があります。 すでに他のコミットをしてしまった場合(つまり、機密情報のコミットが直前のコミットよりも前である場合)は、リベースする必要があります。
<a href="#i-want-to-remove-a-large-file-from-ever-existing-in-repo-history"></a> <a name="remove-large-file-in-repo-history"></a>
### 大容量のファイルに関する履歴を完全に削除したい ### 大容量のファイルに関する履歴を完全に削除したい
削除したいファイルが機密情報である場合は[機密情報を削除する方法](#i-accidentally-committed-and-pushed-files-containing-sensitive-data)を参照してください。 削除したいファイルが機密情報である場合は[機密情報を削除する方法](#undo-sensitive-commit-push)を参照してください。
コミットで大容量のファイルや不要なファイルを削除しても、`.git` フォルダの Git 履歴には残るので、`git clone` したときに余計なファイルまでダウンロードしてしまうことになります。 コミットで大容量のファイルや不要なファイルを削除しても、`.git` フォルダの Git 履歴には残るので、`git clone` したときに余計なファイルまでダウンロードしてしまうことになります。
@ -587,7 +588,7 @@ bfg は最新のコミットにあるファイルには影響しません。
プッシュが成功したら、通常の`git push` が 成功するまで `<number>` を徐々に減らしてください。 プッシュが成功したら、通常の`git push` が 成功するまで `<number>` を徐々に減らしてください。
<a href="i-need-to-change-the-content-of-a-commit-which-is-not-my-last"></a> <a name="change-content-of-commit-not-my-last"></a>
### 直近でないコミットの内容を編集したい ### 直近でないコミットの内容を編集したい
複数(たとえば三件)のコミットを行ったあと、文脈的に最初のコミットに属する作業をし忘れたことに気づいたとします。 複数(たとえば三件)のコミットを行ったあと、文脈的に最初のコミットに属する作業をし忘れたことに気づいたとします。
@ -637,8 +638,7 @@ pick f4037ec The last commit
## ステージ ## ステージ
<a href="#i-want-to-stage-all-tracked-files-and-leave-untracked-files"></a> <a name="stage-tracked-files-and-leave-untracked-files"></a>
### バージョン管理されているファイルを全部ステージしたい ### バージョン管理されているファイルを全部ステージしたい
```sh ```sh
@ -655,7 +655,7 @@ $ git add -u *.txt
$ git add -u src/ $ git add -u src/
``` ```
<a href="#i-need-to-add-staged-changes-to-the-previous-commit"></a> <a name="add-staged-changes-to-previous-commit"></a>
### ステージされた編集を直前のコミットに追加したい ### ステージされた編集を直前のコミットに追加したい
```sh ```sh
@ -688,19 +688,19 @@ $ git add -N filename.x
オプション `e` を使うと、どの行を追加するか手動で選択することができます。 オプション `e` を使うと、どの行を追加するか手動で選択することができます。
コマンド `git diff --cached` あるいは `git diff --staged` を実行すると、ステージした行がローカルに保存されたものと比較して表示されます。 コマンド `git diff --cached` あるいは `git diff --staged` を実行すると、ステージした行がローカルに保存されたものと比較して表示されます。
<a href="stage-in-two-commits"></a> <a name="stage-in-two-commits"></a>
### 一つのファイルに加えた編集を二つの異なるコミットに追加したい ### 一つのファイルに加えた編集を二つの異なるコミットに追加したい
コマンド `git add` はファイル全体をコミットに追加します。 コマンド `git add` はファイル全体をコミットに追加します。
また、`git add -p` を使うと、どの編集を追加するか対話的に選択できます。 また、`git add -p` を使うと、どの編集を追加するか対話的に選択できます。
<a href="selective-unstage-edits"></a> <a name="selective-unstage-edits"></a>
### ステージした編集が多すぎるので、いくつかのコミットに分割したい ### ステージした編集が多すぎるので、いくつかのコミットに分割したい
コマンド `git reset -p` を実行すると、パッチモードのリセットダイアログが開きます。 コマンド `git reset -p` を実行すると、パッチモードのリセットダイアログが開きます。
なお、`git add -p` と似ていますが、"yes" がステージを取り消して次のコミットから除去することを意味する点で異なります。 なお、`git add -p` と似ていますが、"yes" がステージを取り消して次のコミットから除去することを意味する点で異なります。
<a href="unstaging-edits-and-staging-the-unstaged"></a> <a name="unstaging-edits-and-staging-the-unstaged"></a>
### ステージされていない編集をステージし、ステージされた編集のステージを取り消したい ### ステージされていない編集をステージし、ステージされた編集のステージを取り消したい
通常は、ステージされたファイルのステージを一旦全部取り消したあと、コミットしたいものをピックするべきです。 通常は、ステージされたファイルのステージを一旦全部取り消したあと、コミットしたいものをピックするべきです。
@ -721,14 +721,14 @@ $ git stash pop --index 0
## ステージされていない編集 ## ステージされていない編集
<a href="move-unstaged-edits-to-new-branch"></a> <a name="move-unstaged-edits-to-new-branch"></a>
### ステージされていない編集を新しいブランチに移したい ### ステージされていない編集を新しいブランチに移したい
```sh ```sh
$ git checkout -b my-branch $ git checkout -b my-branch
``` ```
<a href="move-unstaged-edits-to-old-branch"></a> <a name="move-unstaged-edits-to-old-branch"></a>
### ステージされていない編集を別の既存のブランチに移したい ### ステージされていない編集を別の既存のブランチに移したい
```sh ```sh
@ -737,7 +737,7 @@ $ git checkout my-branch
$ git stash pop $ git stash pop
``` ```
<a href="i-want-to-discard-my-local-uncommitted-changes"></a> <a name="discard-local-uncommitted-changes"></a>
### コミットされていないローカルの編集を破棄したい ### コミットされていないローカルの編集を破棄したい
ステージされている編集とされていない編集の両方を全て破棄したいときは、次のようにします。 ステージされている編集とされていない編集の両方を全て破棄したいときは、次のようにします。
@ -831,7 +831,7 @@ $ git checkout myFirstFile mySecondFile
$ git checkout . $ git checkout .
``` ```
<a href="i-want-to-discard-all-my-untracked-files"></a> <a name="discard-all-untracked-files"></a>
### バージョン管理されていないファイルを全て破棄したい ### バージョン管理されていないファイルを全て破棄したい
バージョン管理されていないファイルを全て破棄したいときは、次を実行します。 バージョン管理されていないファイルを全て破棄したいときは、次を実行します。
@ -840,7 +840,7 @@ $ git checkout .
$ git clean -f $ git clean -f
``` ```
<a href="I-want-to-unstage-specific-staged-file"></a> <a name="unstage-specific-staged-file"></a>
### 特定のステージされたファイルのステージを取り消したい ### 特定のステージされたファイルのステージを取り消したい
間違えてステージしたが、コミットはしていないファイルが一つまたは複数ある場合です。 間違えてステージしたが、コミットはしていないファイルが一つまたは複数ある場合です。
@ -901,7 +901,7 @@ $ git reset --hard c5bc55a
これで完了です。 これで完了です。
<a href="discard-local-commits"></a> <a name="discard-local-commits"></a>
### ローカルのコミットを破棄して、ブランチをサーバ上と同じ状態にしたい ### ローカルのコミットを破棄して、ブランチをサーバ上と同じ状態にしたい
サーバに編集をプッシュしていないことを確認してください。 サーバに編集をプッシュしていないことを確認してください。
@ -1049,7 +1049,7 @@ HEAD is now at a13b85e
``` ```
この時点で、コミットのコンフリクトが発生しているかもしれません。 この時点で、コミットのコンフリクトが発生しているかもしれません。
コンフリクトを解消する方法は、[interactive rebasing section above](#interactive-rebase) セクションの [**There were conflicts**](#merge-conflict) を参照してください。 コンフリクトを解消する方法は、[対話的 rebase 章上](#interactive-rebase) セクションの [**コンフリクトがあった**](#merge-conflict) を参照してください。
次に、#14 に対応する、マスターに紐づいたブランチを作成しましょう。 次に、#14 に対応する、マスターに紐づいたブランチを作成しましょう。
@ -1077,7 +1077,7 @@ $ git fetch -p upstream
ここで `upstream` は取得したい元のリモートを指します。 ここで `upstream` は取得したい元のリモートを指します。
<a name='restore-a-deleted-branch'></a> <a name="restore-a-deleted-branch"></a>
### 間違ってブランチを削除してしまった ### 間違ってブランチを削除してしまった
いつもリモートにプッシュしているなら大抵大丈夫です。 いつもリモートにプッシュしているなら大抵大丈夫です。
@ -1207,7 +1207,7 @@ README.md foo.txt
(main)$ git push origin :old_name new_name (main)$ git push origin :old_name new_name
``` ```
<a name="i-want-to-checkout-to-a-remote-branch-that-someone-else-is-working-on"></a> <a name="working-on-checkout-remote-branch"></a>
### 他の人が作業しているリモートブランチにチェックアウトしたい ### 他の人が作業しているリモートブランチにチェックアウトしたい
まず、リモートから全ブランチを取得します。 まず、リモートから全ブランチを取得します。
@ -1246,7 +1246,7 @@ $ git push -u <remote> HEAD
$ git push $ git push
``` ```
他のモードが `git push` でどう振る舞うかは、[`push.default` のドキュメント](https://git-scm.com/docs/git-config#git-config-pushdefault)で説明されています。 他のモードが `git push` でどう振る舞うかは、[`push.default` のドキュメント](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushdefault)で説明されています。
### リモートブランチをローカルブランチの upstream に設定したい ### リモートブランチをローカルブランチの upstream に設定したい
@ -1264,7 +1264,7 @@ $ git branch -u [remotename]/[branch]
$ git branch -u [remotename]/[branch] [local-branch] $ git branch -u [remotename]/[branch] [local-branch]
``` ```
<a name="i-want-to-set-my-HEAD-to-track-the-default-remote-branch"></a> <a name="head-to-track-remote-branch"></a>
### 自分の HEAD をデフォルトのリモートブランチを追跡するよう設定したい ### 自分の HEAD をデフォルトのリモートブランチを追跡するよう設定したい
リモートブランチを調べると、自分の HEAD がどのリモートブランチを追跡しているかがわかります。 リモートブランチを調べると、自分の HEAD がどのリモートブランチを追跡しているかがわかります。
@ -1545,7 +1545,7 @@ Changes not staged for commit:
``` ```
- *マージする*場合、ローカルブランチの編集を残したいとき `--ours` を指定し、他方の編集を残したいとき `--theirs` を指定します。 - *マージする*場合、ローカルブランチの編集を残したいとき `--ours` を指定し、他方の編集を残したいとき `--theirs` を指定します。
- *リベースする*場合、ローカルブランチの編集を残したいとき `--theirs` を指定し、他方の編集を残したいとき `--ours` を指定します。このように逆転する理由は[ Git ドキュメントのこのノート](https://git-scm.com/docs/git-rebase#git-rebase---merge)を参照してください。 - *リベースする*場合、ローカルブランチの編集を残したいとき `--theirs` を指定し、他方の編集を残したいとき `--ours` を指定します。このように逆転する理由は[ Git ドキュメントのこのノート](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---merge)を参照してください。
マージがもっと複雑なときは、ビジュアル差分エディタを使うとよいです。 マージがもっと複雑なときは、ビジュアル差分エディタを使うとよいです。
@ -1661,7 +1661,7 @@ $ git log -S "string to find"
* `--all` は全てのブランチから検索します。 * `--all` は全てのブランチから検索します。
* `--reverse` は逆順に表示します。すなわち最初のコミットから表示します。 * `--reverse` は逆順に表示します。すなわち最初のコミットから表示します。
<a name="i-want-to-find-by-author-committer"></a> <a name="find-by-committer"></a>
### author または committer から検索する ### author または committer から検索する
全てのコミットを author または committer の名前から検索するには次のようにします。 全てのコミットを author または committer の名前から検索するには次のようにします。
@ -1694,7 +1694,7 @@ $ git log -- **/*.js
$ git log --name-status -- **/*.js $ git log --name-status -- **/*.js
``` ```
<a name="#i-want-to-view-the-commit-history-for-a-specific-function"></a> <a name="view-commit-history-for-specific-function"></a>
### 特定の関数に関するコミット履歴を見たい ### 特定の関数に関するコミット履歴を見たい
特定の関数の履歴を追跡するには次を実行します。 特定の関数の履歴を追跡するには次を実行します。
@ -1832,7 +1832,7 @@ $ git push origin refs/tags/<tag-name>
## ファイルの追跡 ## ファイルの追跡
<a href="i-want-to-change-a-file-names-capitalization-without-changing-the-contents-of-the-file"></a> <a name="change-file-name-capitalization-without-changing-contents"></a>
### ファイルの内容は変えずに、ファイル名の大文字・小文字を変更したい ### ファイルの内容は変えずに、ファイル名の大文字・小文字を変更したい
```sh ```sh
@ -1846,7 +1846,7 @@ $ git push origin refs/tags/<tag-name>
(main)$ git reset --hard origin/main (main)$ git reset --hard origin/main
``` ```
<a href="remove-from-git"></a> <a name="remove-from-git"></a>
### ファイルを残しつつ Git から削除したい ### ファイルを残しつつ Git から削除したい
```sh ```sh

View File

@ -151,7 +151,6 @@ $ git clone [url] name-of-new-folder
<a name="diff-last"></a> <a name="diff-last"></a>
<!-- ### What did I just commit? --> <!-- ### What did I just commit? -->
### 내가 방금 어떤 커밋을 남겼지? ### 내가 방금 어떤 커밋을 남겼지?
`git commit -a` 로 막 커밋을 남기고 내가 뭐라고 안에 적었더라? 한다고 하고. 최근의 커밋을 현재 HEAD에서 볼 수 있어요. `git commit -a` 로 막 커밋을 남기고 내가 뭐라고 안에 적었더라? 한다고 하고. 최근의 커밋을 현재 HEAD에서 볼 수 있어요.
@ -172,6 +171,7 @@ $ git log -n1 -p
$ git show <commitid>:filename $ git show <commitid>:filename
``` ```
<a name="wrong-thing-in-commit-message"></a>
### 커밋 메세지를 잘못 썼어 ### 커밋 메세지를 잘못 썼어
만약 메시지를 잘못 썼고 아직 푸시를 안했다면, 커밋 메시지 바꾸기를 따라해 볼 수 있어요. 만약 메시지를 잘못 썼고 아직 푸시를 안했다면, 커밋 메시지 바꾸기를 따라해 볼 수 있어요.
@ -256,7 +256,7 @@ $ git push --force-with-lease [remote] [branch]
아니면 [대화형 리베이스](#interactive-rebase)를 쓰고 지우고 싶은 커밋 라인을 지워도 돼요. 아니면 [대화형 리베이스](#interactive-rebase)를 쓰고 지우고 싶은 커밋 라인을 지워도 돼요.
<a name="#force-push"></a> <a name="force-push"></a>
### 수정된 커밋을 푸시했는데, 에러 메세지가 떠 ### 수정된 커밋을 푸시했는데, 에러 메세지가 떠
```sh ```sh
@ -283,7 +283,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
절대로 아무도 같은 브랜치를 안 쓰거나, 절대로 브랜치에 업데이트를 해야할때 `--force` (`-f`) 옵션을 쓸 수 있지만 일반적으론 피하는게 좋아요. 절대로 아무도 같은 브랜치를 안 쓰거나, 절대로 브랜치에 업데이트를 해야할때 `--force` (`-f`) 옵션을 쓸 수 있지만 일반적으론 피하는게 좋아요.
<a href="undo-git-reset-hard"></a> <a name="undo-git-reset-hard"></a>
### 하드 리셋을 해버렸는데 되돌리고 싶어 ### 하드 리셋을 해버렸는데 되돌리고 싶어
만약 하드 리셋을 했다고 해도 커밋을 돌릴 순 있어요. 깃은 며칠간은 로그를 가지고 있거든요. 만약 하드 리셋을 했다고 해도 커밋을 돌릴 순 있어요. 깃은 며칠간은 로그를 가지고 있거든요.
@ -302,7 +302,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
계속 할 수 있을거에요. 계속 할 수 있을거에요.
<a href="undo-a-commit-merge"></a> <a name="undo-a-commit-merge"></a>
### 머지를 실수로 커밋, 푸시해버렸어 ### 머지를 실수로 커밋, 푸시해버렸어
만약 실수로 머지할 준비가 안된 피쳐 브랜치를 메인 브랜치에 머지했어도 되돌릴 순 있어요. 만약 실수로 머지할 준비가 안된 피쳐 브랜치를 메인 브랜치에 머지했어도 되돌릴 순 있어요.
@ -321,7 +321,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
## 스테이지 ## 스테이지
<a href="#i-need-to-add-staged-changes-to-the-previous-commit"></a> <a name="add-staged-changes-to-previous-commit"></a>
### 지난 커밋에 스테이지 변경점을 추가하고 싶어 ### 지난 커밋에 스테이지 변경점을 추가하고 싶어
```sh ```sh
@ -345,12 +345,12 @@ $ git add -N filename.x
그 다음 임의적으로 라인들을 골라 추가해주려면 `e`옵션이 필요할거에요. `git diff --cached``git diff --staged`는 로컬에 저장된 부분과 스테이지에 있는 라인들을 비교해서 보여줄 거에요. 그 다음 임의적으로 라인들을 골라 추가해주려면 `e`옵션이 필요할거에요. `git diff --cached``git diff --staged`는 로컬에 저장된 부분과 스테이지에 있는 라인들을 비교해서 보여줄 거에요.
<a href="stage-in-two-commits"></a> <a name="stage-in-two-commits"></a>
### 하나의 파일 변경점을 두개의 다른 커밋에 남기고 싶어 ### 하나의 파일 변경점을 두개의 다른 커밋에 남기고 싶어
`git add`는 전체 파일들을 커밋에 추가해요. `git add -p`는 대화형으로 추가하고픈 변경점들을 고를 수 있어요. `git add`는 전체 파일들을 커밋에 추가해요. `git add -p`는 대화형으로 추가하고픈 변경점들을 고를 수 있어요.
<a href="unstaging-edits-and-staging-the-unstaged"></a> <a name="unstaging-edits-and-staging-the-unstaged"></a>
### 아직 스테이지에 안 올라간 변경점을 스테이지에 추가하고, 스테이지에 있는 변경점을 다시 빼고 싶어 ### 아직 스테이지에 안 올라간 변경점을 스테이지에 추가하고, 스테이지에 있는 변경점을 다시 빼고 싶어
이건 좀 꼼수인데요, 스테이지 전인 파일들을 스테이시해서 빼두고선 리셋 할 수 있을거에요. 그 다음 스테이시를 다시 불러와 추가를 해요. 이건 좀 꼼수인데요, 스테이지 전인 파일들을 스테이시해서 빼두고선 리셋 할 수 있을거에요. 그 다음 스테이시를 다시 불러와 추가를 해요.
@ -364,14 +364,14 @@ $ git add -A
## 스테이지 전의 변경점 ## 스테이지 전의 변경점
<a href="move-unstaged-edits-to-new-branch"></a> <a name="move-unstaged-edits-to-new-branch"></a>
### 스테이지 전의 변경점을 새 브랜치로 옮기고 싶어 ### 스테이지 전의 변경점을 새 브랜치로 옮기고 싶어
```sh ```sh
$ git checkout -b my-branch $ git checkout -b my-branch
``` ```
<a href="move-unstaged-edits-to-old-branch"></a> <a name="move-unstaged-edits-to-old-branch"></a>
### 스테이지전 변경점을 만들어둔 다른 브랜치로 옮기고 싶어 ### 스테이지전 변경점을 만들어둔 다른 브랜치로 옮기고 싶어
```sh ```sh
@ -380,7 +380,7 @@ $ git checkout my-branch
$ git stash pop $ git stash pop
``` ```
<a href="i-want-to-discard-my-local-uncommitted-changes"></a> <a name="discard-local-uncommitted-changes"></a>
### 내 로컬에 있는 커밋 안된 변경점을 다 무시하고 싶어 (스테이징 됐던 안됐던) ### 내 로컬에 있는 커밋 안된 변경점을 다 무시하고 싶어 (스테이징 됐던 안됐던)
만약 모든 스테이징 됐거나 안 된 변경점을 버리고 싶다면 이렇게 해요: 만약 모든 스테이징 됐거나 안 된 변경점을 버리고 싶다면 이렇게 해요:
@ -472,7 +472,7 @@ $ git checkout myFirstFile mySecondFile
$ git checkout . $ git checkout .
``` ```
<a href="i-want-to-discard-all-my-untracked-files"></a> <a name="discard-all-untracked-files"></a>
### 트래킹 안된 파일들 다 지우고 싶어 ### 트래킹 안된 파일들 다 지우고 싶어
트래킹 안된 파일들 다 지우고 싶을 땐 트래킹 안된 파일들 다 지우고 싶을 땐
@ -529,7 +529,7 @@ $ git reset --hard c5bc55a
끝! 끝!
<a href="discard-local-commits"></a> <a name="discard-local-commits"></a>
### 로컬의 커밋을 지워서 서버에 있는 내 브랜치와 맞추고 싶어 ### 로컬의 커밋을 지워서 서버에 있는 내 브랜치와 맞추고 싶어
서버에 변경점을 푸시 안했는지부터 확인해요. 서버에 변경점을 푸시 안했는지부터 확인해요.
@ -700,7 +700,7 @@ $ git fetch -p upstream
여기서, `upstream`은 패치로 가져오려는 리모트 레파지토리에요. 여기서, `upstream`은 패치로 가져오려는 리모트 레파지토리에요.
<a name='restore-a-deleted-branch'></a> <a name="restore-a-deleted-branch"></a>
### 브랜치를 지워버렸어 ### 브랜치를 지워버렸어
주기적으로 리모트으로 푸시한다면, 대부분은 안전해야 해요. 그치만 가끔은 브랜치를 지울 수 있어요. 새 브랜치를 만들고 파일을 하나 만들었다고 해보죠: 주기적으로 리모트으로 푸시한다면, 대부분은 안전해야 해요. 그치만 가끔은 브랜치를 지울 수 있어요. 새 브랜치를 만들고 파일을 하나 만들었다고 해보죠:
@ -818,7 +818,7 @@ README.md foo.txt
(main)$ git branch -m old-name new-name (main)$ git branch -m old-name new-name
``` ```
<a name="i-want-to-checkout-to-a-remote-branch-that-someone-else-is-working-on"></a> <a name="working-on-checkout-remote-branch"></a>
### 다른 사람이 작업중인 리모트 브랜치로 체크아웃 하고 싶어 ### 다른 사람이 작업중인 리모트 브랜치로 체크아웃 하고 싶어
우선, 리모트 레파지토리에서 모든 브랜치를 패치 받아요: 우선, 리모트 레파지토리에서 모든 브랜치를 패치 받아요:
@ -858,7 +858,7 @@ $ git push -u <remote> HEAD
$ git push $ git push
``` ```
`git push`의 다른 모드의 동작은 [`push.default` 문서](https://git-scm.com/docs/git-config#git-config-pushdefault)에 설명돼 있어요. `git push`의 다른 모드의 동작은 [`push.default` 문서](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushdefault)에 설명돼 있어요.
### 리모트 브랜치를 로컬 브랜치를 위한 업스트림으로 설정하고 싶어 ### 리모트 브랜치를 로컬 브랜치를 위한 업스트림으로 설정하고 싶어
@ -876,8 +876,7 @@ $ git branch -u [remotename]/[branch]
$ git branch -u [remotename]/[branch] [local-branch] $ git branch -u [remotename]/[branch] [local-branch]
``` ```
<a name="i-want-to-set-my-HEAD-to-track-the-default-remote-branch"></a> <a name="head-to-track-remote-branch"></a>
### HEAD를 기본 리모트 브랜치로 트래킹하도록 설정하고 싶어 ### HEAD를 기본 리모트 브랜치로 트래킹하도록 설정하고 싶어
리모트 브랜치를 확인해보는 것으로, HEAD가 트래킹 중인 리모트 브랜치를 볼 수 있어요. 몇몇 경우에는, 원하던 브랜치가 아닐거에요. 리모트 브랜치를 확인해보는 것으로, HEAD가 트래킹 중인 리모트 브랜치를 볼 수 있어요. 몇몇 경우에는, 원하던 브랜치가 아닐거에요.
@ -1101,7 +1100,6 @@ noop
* 대신해서 `HEAD~2` 또는 더 기존 항목을 리베이스 * 대신해서 `HEAD~2` 또는 더 기존 항목을 리베이스
<a name="merge-conflict"></a> <a name="merge-conflict"></a>
#### 충돌이 있어 #### 충돌이 있어
리베이스를 똑바로 끝내지 못했다면, 충돌을 해결해야 할거에요. 리베이스를 똑바로 끝내지 못했다면, 충돌을 해결해야 할거에요.
@ -1137,7 +1135,7 @@ Changes not staged for commit:
``` ```
- *머지*할때, `--ours`를 쓰면 로컬 브랜치의 변경점 유지하고, `--theirs` 는 다른 브랜치의 변경점를 유지해요. - *머지*할때, `--ours`를 쓰면 로컬 브랜치의 변경점 유지하고, `--theirs` 는 다른 브랜치의 변경점를 유지해요.
- *리베이스*할 땐, `--theirs`가 로컬 브랜치의 변경점을 유지하고 `--ours`는 다른 브랜치의 변경점을 유지해요. 이런 차이에 관한 설명은 Git 정식 문서 중 [이 문서](https://git-scm.com/docs/git-rebase#git-rebase---merge)를 보세요. - *리베이스*할 땐, `--theirs`가 로컬 브랜치의 변경점을 유지하고 `--ours`는 다른 브랜치의 변경점을 유지해요. 이런 차이에 관한 설명은 Git 정식 문서 중 [이 문서](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---merge)를 보세요.
만약 머지가 더 복잡하면, 비주얼 디프 에디터를 쓸 수도 있어요: 만약 머지가 더 복잡하면, 비주얼 디프 에디터를 쓸 수도 있어요:
@ -1234,7 +1232,7 @@ $ git log -S "string to find"
* `--reverse` 반대의 순서로 출력해요, 변경점의 첫번째 커밋이 보일꺼란 거죠. * `--reverse` 반대의 순서로 출력해요, 변경점의 첫번째 커밋이 보일꺼란 거죠.
<a name="i-want-to-find-by-author-committer"></a> <a name="find-by-committer"></a>
### 작성자나 커미터를 찾고 싶어 ### 작성자나 커미터를 찾고 싶어
작성자나 커미터의 모든 커밋을 찾으려면 이렇게 쓸 수 있어요: 작성자나 커미터의 모든 커밋을 찾으려면 이렇게 쓸 수 있어요:
@ -1279,7 +1277,6 @@ $ git tag --contains <commitid>
## 서브모듈 ## 서브모듈
<a name="clone-submodules"></a> <a name="clone-submodules"></a>
### 모든 서브모듈을 클론하기 ### 모든 서브모듈을 클론하기
```sh ```sh
@ -1366,7 +1363,7 @@ $ git archive --format zip --output /full/path/to/zipfile.zip main
## 파일 추적하기 ## 파일 추적하기
<a href="i-want-to-change-a-file-names-capitalization-without-changing-the-contents-of-the-file"></a> <a name="change-file-name-capitalization-without-changing-contents"></a>
### 파일 내용엔 변경이 없이 파일 이름을 앞글자만 대문자로 바꾸고 싶어 ### 파일 내용엔 변경이 없이 파일 이름을 앞글자만 대문자로 바꾸고 싶어
@ -1381,7 +1378,7 @@ $ git archive --format zip --output /full/path/to/zipfile.zip main
(main)$ git reset --hard origin/main (main)$ git reset --hard origin/main
``` ```
<a href="remove-from-git"></a> <a name="remove-from-git"></a>
### 파일을 로컬에는 보관하고 깃에서 지우고 싶어 ### 파일을 로컬에는 보관하고 깃에서 지우고 싶어
```sh ```sh

View File

@ -276,6 +276,7 @@ $ git log -n1 -p
$ git show <commitid>:filename $ git show <commitid>:filename
``` ```
<a name="wrong-thing-in-commit-message"></a>
### Я неправильно написал сообщение коммита ### Я неправильно написал сообщение коммита
Если Вы неправильно сохранили коммит, но еще не сделали `push`, то для исправления сообщения коммита сделайте следующее: Если Вы неправильно сохранили коммит, но еще не сделали `push`, то для исправления сообщения коммита сделайте следующее:
@ -358,7 +359,7 @@ $ git push --force-with-lease [remote] [branch]
Или сделайте [интерактивное перебазирование](#interactive-rebase) и удалите строки ненужных коммитов. Или сделайте [интерактивное перебазирование](#interactive-rebase) и удалите строки ненужных коммитов.
<a name="#force-push"></a> <a name="force-push"></a>
### Я пытаюсь опубликовать исправленный коммит, но получаю сообщение об ошибке ### Я пытаюсь опубликовать исправленный коммит, но получаю сообщение об ошибке
```sh ```sh
@ -381,7 +382,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Если Вы *абсолютно* уверены, что никто кроме Вас не работает с данной веткой или Вы хотите обновить вершину ветви в любом случае, то используйте `--force` (`-f`), но вообще этого следует избегать. Если Вы *абсолютно* уверены, что никто кроме Вас не работает с данной веткой или Вы хотите обновить вершину ветви в любом случае, то используйте `--force` (`-f`), но вообще этого следует избегать.
<a href="undo-git-reset-hard"></a> <a name="undo-git-reset-hard"></a>
### Я случайно сделал жесткий сброс (--hard) и теперь хочу вернуть свои изменения ### Я случайно сделал жесткий сброс (--hard) и теперь хочу вернуть свои изменения
Если Вы случайно сделали `git reset --hard`, то вы можете вернуть назад коммиты, т.к. Git несколько дней хранит все действия в журнале. Если Вы случайно сделали `git reset --hard`, то вы можете вернуть назад коммиты, т.к. Git несколько дней хранит все действия в журнале.
@ -400,7 +401,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
И Вы сможете продолжить работу. И Вы сможете продолжить работу.
<a href="undo-a-commit-merge"></a> <a name="undo-a-commit-merge"></a>
### Я случайно опубликовал ненужное слияние ### Я случайно опубликовал ненужное слияние
Если Вы случайно сделали слияние в основную ветку разработки до того, как были сделаны все необходимые изменения, Вы по-прежнему можете отменить слияние. Но есть одна загвоздка: Коммит слияния имеет более одного родителя (обычно два). Если Вы случайно сделали слияние в основную ветку разработки до того, как были сделаны все необходимые изменения, Вы по-прежнему можете отменить слияние. Но есть одна загвоздка: Коммит слияния имеет более одного родителя (обычно два).
@ -413,7 +414,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Заметка: номер родителя - это не идентификатор коммита. Допустим, коммит слияния имеет строчку `Merge: 8e2ce2d 86ac2e7`. Номер родителя - это порядковый номер (отсчет с 1) нужного родителя в этой строчке, первый идентификатор - номер 1, второй - номер 2 и т.д. Заметка: номер родителя - это не идентификатор коммита. Допустим, коммит слияния имеет строчку `Merge: 8e2ce2d 86ac2e7`. Номер родителя - это порядковый номер (отсчет с 1) нужного родителя в этой строчке, первый идентификатор - номер 1, второй - номер 2 и т.д.
<a href="undo-sensitive-commit-push"></a> <a name="undo-sensitive-commit-push"></a>
### Я случайно закоммитил и опубликовал файлы с конфиденциальными данными ### Я случайно закоммитил и опубликовал файлы с конфиденциальными данными
Если Вы случайно опубликовали файлы, содержащие конфиденциальные данные (пароли, ключи и пр.), Вы можете изменить последний коммит с помощью amend. Помните, что как только Вы опубликовали коммит, то Вы должны считать всё его содержание скомпрометированным. С помощью дальнейших шагов можно удалить конфиденциальную информацию из публичного репозиторий или из Вашей локальной копии, вы **не сможете** удалить свою конфиденциальную информацию у людей, которые могли успеть скопировать себе её. Если Вы закоммитили пароль, то **незамедлительно поменяйте его**. Если Вы закоммитили ключ, то **незамедлительно сгенерируйте новый**. Изменения опубликованного коммита недостаточно, потому что кто-нибудь мог скопировать исходный коммит до того, как Вы успели его исправить. Если Вы случайно опубликовали файлы, содержащие конфиденциальные данные (пароли, ключи и пр.), Вы можете изменить последний коммит с помощью amend. Помните, что как только Вы опубликовали коммит, то Вы должны считать всё его содержание скомпрометированным. С помощью дальнейших шагов можно удалить конфиденциальную информацию из публичного репозиторий или из Вашей локальной копии, вы **не сможете** удалить свою конфиденциальную информацию у людей, которые могли успеть скопировать себе её. Если Вы закоммитили пароль, то **незамедлительно поменяйте его**. Если Вы закоммитили ключ, то **незамедлительно сгенерируйте новый**. Изменения опубликованного коммита недостаточно, потому что кто-нибудь мог скопировать исходный коммит до того, как Вы успели его исправить.
@ -444,10 +445,10 @@ echo sensitive_file >> .gitignore
Если Вы успели сделать другие коммиты после коммита с конфиденциальными данными, то Вам нужно использовать rebase. Если Вы успели сделать другие коммиты после коммита с конфиденциальными данными, то Вам нужно использовать rebase.
<a href="#i-want-to-remove-a-large-file-from-ever-existing-in-repo-history"></a> <a name="remove-large-file-in-repo-history"></a>
### Я хочу удалить большой файл из истории репозитория ### Я хочу удалить большой файл из истории репозитория
Если вы хотите удалить пароль или другую конфиденциальную информацию, то вместо этого смотрите [Я случайно закоммитил и опубликовал файлы с конфиденциальными данными](#%D0%AF-%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D0%BE-%D0%B7%D0%B0%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%B8%D0%BB-%D0%B8-%D0%BE%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%BE%D0%B2%D0%B0%D0%BB-%D1%84%D0%B0%D0%B9%D0%BB%D1%8B-%D1%81-%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%BC%D0%B8-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%BC%D0%B8). Если вы хотите удалить пароль или другую конфиденциальную информацию, то вместо этого смотрите [Я случайно закоммитил и опубликовал файлы с конфиденциальными данными](#undo-sensitive-commit-push).
Даже если вы удалите большие или ненужные файлы из последнего коммита, они останутся в истоии Git, в подкаталоге `.git` вашего репозитория и `git clone` будет загружать ненужные файлы. Даже если вы удалите большие или ненужные файлы из последнего коммита, они останутся в истоии Git, в подкаталоге `.git` вашего репозитория и `git clone` будет загружать ненужные файлы.
@ -515,7 +516,7 @@ echo sensitive_file >> .gitignore
``` ```
После того как только команда push сработала в первый раз, постепенно уменьшайте `<number>`, пока не сработает обычная `git push`. После того как только команда push сработала в первый раз, постепенно уменьшайте `<number>`, пока не сработает обычная `git push`.
<a href="i-need-to-change-the-content-of-a-commit-which-is-not-my-last"></a> <a name="change-content-of-commit-not-my-last"></a>
### Мне нужно изменить содержимое коммита, который не является последним ### Мне нужно изменить содержимое коммита, который не является последним
Пусть Вы сделали несколько (например, три) коммитов и после этого поняли, что упустили что-то, что по смыслу относится к первому из этих трёх коммитов. Вы могли бы сделать новый коммит, содержащий эти изменения, и тогда у Вас была бы чистая кодовая база, но Ваши коммиты не были бы атомарными (т.е. связанные изменения не содержались бы в едином коммите). В такой ситуации Вы бы хотели изменить коммит, к которому относятся эти изменения, а следующие коммиты оставить как есть. В таком случае Вас может спасти `git rebase`. Пусть Вы сделали несколько (например, три) коммитов и после этого поняли, что упустили что-то, что по смыслу относится к первому из этих трёх коммитов. Вы могли бы сделать новый коммит, содержащий эти изменения, и тогда у Вас была бы чистая кодовая база, но Ваши коммиты не были бы атомарными (т.е. связанные изменения не содержались бы в едином коммите). В такой ситуации Вы бы хотели изменить коммит, к которому относятся эти изменения, а следующие коммиты оставить как есть. В таком случае Вас может спасти `git rebase`.
@ -558,7 +559,7 @@ pick f4037ec The last commit
## Подготовка изменений (staging) ## Подготовка изменений (staging)
<a href="#i-need-to-add-staged-changes-to-the-previous-commit"></a> <a name="add-staged-changes-to-previous-commit"></a>
### Мне нужно добавить подготовленные изменения в предыдущий коммит ### Мне нужно добавить подготовленные изменения в предыдущий коммит
```sh ```sh
@ -590,17 +591,17 @@ $ git add -N filename.x
Затем используйте опцию `e` для ручного выбора строк. Запустив `git diff --cached` или Затем используйте опцию `e` для ручного выбора строк. Запустив `git diff --cached` или
`git diff --staged`, Вы увидите какие строки вы подготовили по-сравнению с тем, что сохранено в рабочей копии. `git diff --staged`, Вы увидите какие строки вы подготовили по-сравнению с тем, что сохранено в рабочей копии.
<a href="stage-in-two-commits"></a> <a name="stage-in-two-commits"></a>
### Я хочу добавить изменения одного файла в два разных коммита ### Я хочу добавить изменения одного файла в два разных коммита
`git add` добавляет в коммит весь файл целиком. `git add -p` позволяет интерактивно выбрать изменения, которые Вы хотите добавить. `git add` добавляет в коммит весь файл целиком. `git add -p` позволяет интерактивно выбрать изменения, которые Вы хотите добавить.
<a href="selective-unstage-edits"></a> <a name="selective-unstage-edits"></a>
### Я подготовил слишком много правок и теперь хочу разделить их на несколько отдельных коммитов ### Я подготовил слишком много правок и теперь хочу разделить их на несколько отдельных коммитов
`git reset -p` откроет интерактивный диалог сброса. Это похоже на `git add -p`, за исключением того, что выбор "yes" уберёт правку из готовящегося коммита. `git reset -p` откроет интерактивный диалог сброса. Это похоже на `git add -p`, за исключением того, что выбор "yes" уберёт правку из готовящегося коммита.
<a href="unstaging-edits-and-staging-the-unstaged"></a> <a name="unstaging-edits-and-staging-the-unstaged"></a>
### Я хочу подготовить свои неподготовленные правки и убрать из подготовки то, что уже подготовлено ### Я хочу подготовить свои неподготовленные правки и убрать из подготовки то, что уже подготовлено
Это сложно. Лучшее, что я смог придумать это отложить (stash) неподготовленные изменения. Затем сделать сброс. После этого вернуть отложенные изменения и добавить их. Это сложно. Лучшее, что я смог придумать это отложить (stash) неподготовленные изменения. Затем сделать сброс. После этого вернуть отложенные изменения и добавить их.
@ -614,14 +615,14 @@ $ git add -A
## Неподготовленные правки ## Неподготовленные правки
<a href="move-unstaged-edits-to-new-branch"></a> <a name="move-unstaged-edits-to-new-branch"></a>
### Я хочу переместить мои неподготовленные правки в новую ветку ### Я хочу переместить мои неподготовленные правки в новую ветку
```sh ```sh
$ git checkout -b my-branch $ git checkout -b my-branch
``` ```
<a href="move-unstaged-edits-to-old-branch"></a> <a name="move-unstaged-edits-to-old-branch"></a>
### Я хочу переместить неподготовленные правки в другую существующую ветку ### Я хочу переместить неподготовленные правки в другую существующую ветку
```sh ```sh
@ -630,7 +631,7 @@ $ git checkout my-branch
$ git stash pop $ git stash pop
``` ```
<a href="i-want-to-discard-my-local-uncommitted-changes"></a> <a name="discard-local-uncommitted-changes"></a>
### Я хочу отменить мои локальные несохраненные изменения (подготовленные и неподготовленные) ### Я хочу отменить мои локальные несохраненные изменения (подготовленные и неподготовленные)
Если Вы хотите отменить все подготовленные и неподготовленные изменения, то можете сделать так: Если Вы хотите отменить все подготовленные и неподготовленные изменения, то можете сделать так:
@ -722,7 +723,7 @@ $ git checkout myFirstFile mySecondFile
```sh ```sh
$ git checkout . $ git checkout .
``` ```
<a href="i-want-to-discard-all-my-untracked-files"></a> <a name="discard-all-untracked-files"></a>
### Я хочу удалить все неотслеживаемые файлы ### Я хочу удалить все неотслеживаемые файлы
Когда Вы хотите удалить все неотслеживаемые файлы Когда Вы хотите удалить все неотслеживаемые файлы
@ -731,7 +732,7 @@ $ git checkout .
$ git clean -f $ git clean -f
``` ```
<a href="I-want-to-unstage-specific-staged-file"></a> <a name="unstage-specific-staged-file"></a>
### Я хочу убрать заданный файл из подготовленного ### Я хочу убрать заданный файл из подготовленного
Иногда один или несколько неотслеживаемых файлов ненароком оказываются в подготовленном. Чтобы убрать их из подготовленного: Иногда один или несколько неотслеживаемых файлов ненароком оказываются в подготовленном. Чтобы убрать их из подготовленного:
@ -789,7 +790,7 @@ $ git reset --hard c5bc55a
Готово. Готово.
<a href="discard-local-commits"></a> <a name="discard-local-commits"></a>
### Я хочу отменить локальные коммиты, чтобы моя ветка стала такой же как на сервере ### Я хочу отменить локальные коммиты, чтобы моя ветка стала такой же как на сервере
Подтвердите, что не хотите отправлять изменения на сервер. Подтвердите, что не хотите отправлять изменения на сервер.
@ -1074,7 +1075,7 @@ README.md foo.txt
(main)$ git branch -m old-name new-name (main)$ git branch -m old-name new-name
``` ```
<a name="i-want-to-checkout-to-a-remote-branch-that-someone-else-is-working-on"></a> <a name="working-on-checkout-remote-branch"></a>
### Я хочу перейти на удаленную ветку, над которой работает кто-то еще ### Я хочу перейти на удаленную ветку, над которой работает кто-то еще
Во-первых, получим все ветки из удаленного репозитория: Во-первых, получим все ветки из удаленного репозитория:
@ -1131,7 +1132,7 @@ $ git branch -u [remotename]/[branch]
$ git branch -u [remotename]/[branch] [local-branch] $ git branch -u [remotename]/[branch] [local-branch]
``` ```
<a name="i-want-to-set-my-HEAD-to-track-the-default-remote-branch"></a> <a name="head-to-track-remote-branch"></a>
### Я хочу настроить HEAD на отслеживание основной удаленной ветки ### Я хочу настроить HEAD на отслеживание основной удаленной ветки
При просмотре удаленных веток можно увидеть какую удаленную ветку отслеживает HEAD. Может оказаться, что это не та ветка что нужно. При просмотре удаленных веток можно увидеть какую удаленную ветку отслеживает HEAD. Может оказаться, что это не та ветка что нужно.
@ -1386,7 +1387,7 @@ Changes not staged for commit:
``` ```
- Во время *слияния* используйте `--ours` для сохранения изменений из локальной ветки или `--theirs` для сохранения изменений из другой ветки. - Во время *слияния* используйте `--ours` для сохранения изменений из локальной ветки или `--theirs` для сохранения изменений из другой ветки.
- Во время *перебазирования* используйте `--theirs` для сохранения изменений из локальной ветки или `--ours` для сохранения изменений из другой ветки. Для объяснения такого обмена см. [эту заметку в документации Git](https://git-scm.com/docs/git-rebase#git-rebase---merge). - Во время *перебазирования* используйте `--theirs` для сохранения изменений из локальной ветки или `--ours` для сохранения изменений из другой ветки. Для объяснения такого обмена см. [эту заметку в документации Git](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---merge).
Если слияние более сложное, можете воспользоваться визуальным редактором различий: Если слияние более сложное, можете воспользоваться визуальным редактором различий:
@ -1482,7 +1483,7 @@ $ git log -S "string to find"
- `--reverse` выводит коммиты в обратном порядке, это значит, что вверху будет первый коммит, в котором сделано это изменение. - `--reverse` выводит коммиты в обратном порядке, это значит, что вверху будет первый коммит, в котором сделано это изменение.
<a name="i-want-to-find-by-author-committer"></a> <a name="find-by-committer"></a>
### Я хочу искать по автору или сохранившему изменения (committer) ### Я хочу искать по автору или сохранившему изменения (committer)
Найти все коммиты по автору или сохранившему изменения: Найти все коммиты по автору или сохранившему изменения:
@ -1514,7 +1515,7 @@ $ git log -- **/*.js
$ git log --name-status -- **/*.js $ git log --name-status -- **/*.js
``` ```
<a name="#i-want-to-view-the-commit-history-for-a-specific-function"></a> <a name="view-commit-history-for-specific-function"></a>
### Я хочу посмотреть историю коммитов для отдельной функции ### Я хочу посмотреть историю коммитов для отдельной функции
Для отслеживания эволюции отдельной функции Вы можете использовать: Для отслеживания эволюции отдельной функции Вы можете использовать:
@ -1639,7 +1640,7 @@ $ git push origin refs/tags/<tag-name>
## Отслеживание файлов ## Отслеживание файлов
<a href="i-want-to-change-a-file-names-capitalization-without-changing-the-contents-of-the-file"></a> <a name="change-file-name-capitalization-without-changing-contents"></a>
### Я хочу изменить регистр в имени файла, не меняя содержимое файла ### Я хочу изменить регистр в имени файла, не меняя содержимое файла
```sh ```sh
@ -1653,7 +1654,7 @@ $ git push origin refs/tags/<tag-name>
(main)$ git reset --hard origin/main (main)$ git reset --hard origin/main
``` ```
<a href="remove-from-git"></a> <a name="remove-from-git"></a>
### Я хочу удалить файл из git, но оставить сам файл ### Я хочу удалить файл из git, но оставить сам файл
```sh ```sh

View File

@ -296,6 +296,7 @@ Nếu bạn muốn xem một file tại một commit cụ thể, bạn cũng có
$ git show <commitid>:filename $ git show <commitid>:filename
``` ```
<a name="wrong-thing-in-commit-message"></a>
### Tôi đã viết sai vài thứ trong message (thông điệp) của commit ### Tôi đã viết sai vài thứ trong message (thông điệp) của commit
Nếu bạn đã viết sai thứ gì đó và commit chưa được push lên, bạn có thể làm theo cách sau để thay đổi message của commit mà không làm thay đổi commit: Nếu bạn đã viết sai thứ gì đó và commit chưa được push lên, bạn có thể làm theo cách sau để thay đổi message của commit mà không làm thay đổi commit:
@ -348,6 +349,58 @@ $ git commit --amend --no-edit
Cách này đăc biệt hữu ích khi bạn đang mở một bản patch và bạn đã commit một file không cần thiết và cần force push để cập nhật bản patch trên remote. Dòng `--no-edit` được dùng để giữ không thay đổi message cho commit hiện tại. Cách này đăc biệt hữu ích khi bạn đang mở một bản patch và bạn đã commit một file không cần thiết và cần force push để cập nhật bản patch trên remote. Dòng `--no-edit` được dùng để giữ không thay đổi message cho commit hiện tại.
<a name="delete-pushed-commit"></a>
### Tôi muốn chuyển một thay đổi từ commit sang commit khác
Nếu bạn đã thực hiện một commit bao gồm các thay đổi phù hợp hơn với một commit khác, bạn có thể di chuyển các thay đổi sang commit khác bằng cách sử dụng rebase tương tác (interactive rebase). Đó là câu trả lời từ [stackoverflow](https://stackoverflow.com/a/54985304/2491502).
Ví dụ: bạn có ba commit (a, b, c). Trên b, bạn đã thay đổi file1 và file2 và bạn muốn chuyển thay đổi trên file1 từ commit b sang commit a.
Đầu tiên, rebase interactively:
```sh
$ git rebase -i HEAD~3
```
Editor sẽ hiện lên như bên dưới:
```sh
pick a
pick b
pick c
```
Sửa 2 dòng với a và b thành edit:
```sh
edit a
edit b
pick c
```
Lưu và đóng Editor. Bạn sẽ được đưa tới commit b. Bây giờ, hãy reset các thay đổi của file1:
```sh
$ git reset HEAD~1 file1
```
Thao tác trên sẽ unstash những thay đổi trong file1. Tiếp tục, stash những thay đổi đó và tiếp tục rebase:
```sh
$ git stash
$ git rebase --continue
```
Bây giờ bạn sẽ quay lại chỉnh sửa commit a. Unstash các thay đổi sau đó thêm chúng vào commit hiện tại và tiếp tục rebase:
```sh
$ git stash pop
$ git add file1
$ git commit --amend --no-edit
$ git rebase --continue
```
Bây giờ quá trình rebase của bạn đã hoàn tất, với những thay đổi từ b trên a. Nếu bạn muốn di chuyển các thay đổi từ b sang c, bạn sẽ phải thực hiện hai lần rebase vì c đứng trước b: một để lấy các thay đổi ra khỏi b, sau đó một để chỉnh sửa c và thêm các thay đổi đã stash.
<a name="delete-pushed-commit"></a> <a name="delete-pushed-commit"></a>
### Tôi muốn xoá hoặc loại bỏ commit mới nhất ### Tôi muốn xoá hoặc loại bỏ commit mới nhất
@ -378,7 +431,7 @@ $ git push --force-with-lease [remote] [branch]
Hoặc thực hiện một [interactive rebase](#interactive-rebase) và loại bỏ các dòng tương ứng với các commit bạn muốn loại bỏ. Hoặc thực hiện một [interactive rebase](#interactive-rebase) và loại bỏ các dòng tương ứng với các commit bạn muốn loại bỏ.
<a name="#force-push"></a> <a name="force-push"></a>
### Tôi đã cố gắng push commit đã sửa đổi lên remote, nhưng tôi gặp thông báo lỗi ### Tôi đã cố gắng push commit đã sửa đổi lên remote, nhưng tôi gặp thông báo lỗi
```sh ```sh
@ -401,7 +454,7 @@ Nói chung, **tránh force push**. Tốt nhất là tạo và push một commit
Nếu bạn *hoàn toàn chắc chắn* rằng không ai đang làm việc trên cùng một nhánh hoặc bạn muốn cập nhật đỉnh nhánh (tip of branch) *vô điều kiện*, bạn có thể sử dụng `--force` (`-f`), nhưng cách này nói chung nên tránh. Nếu bạn *hoàn toàn chắc chắn* rằng không ai đang làm việc trên cùng một nhánh hoặc bạn muốn cập nhật đỉnh nhánh (tip of branch) *vô điều kiện*, bạn có thể sử dụng `--force` (`-f`), nhưng cách này nói chung nên tránh.
<a href="undo-git-reset-hard"></a> <a name="undo-git-reset-hard"></a>
### Tôi đã vô tình thực hiện hard reset và tôi muốn các thay đổi của tôi. ### Tôi đã vô tình thực hiện hard reset và tôi muốn các thay đổi của tôi.
Nếu vô tình bạn thực hiện `git reset --hard`, bạn có thể vẫn phục hồi lại được commit của bạn, vì git giữ một bản log cho tất cả mọi thứ trong vài ngày. Nếu vô tình bạn thực hiện `git reset --hard`, bạn có thể vẫn phục hồi lại được commit của bạn, vì git giữ một bản log cho tất cả mọi thứ trong vài ngày.
@ -420,7 +473,7 @@ Bạn sẽ thấy danh sách các commit gần đây và một commit để rese
Thế này là xong. Thế này là xong.
<a href="undo-a-commit-merge"></a> <a name="undo-a-commit-merge"></a>
### Tôi vô tình commit và đẩy lên một merge ### Tôi vô tình commit và đẩy lên một merge
Nếu bạn vô tình merge một nhánh tính năng mới vào nhánh phát triển chính trước khi sẵn sàng để merge, bạn vẫn có thể đảo ngược merge. Nhưng có một điểm phải nắm được: Một commit merge có một hoặc nhiều hơn một parent (gốc) (thường là 2). Nếu bạn vô tình merge một nhánh tính năng mới vào nhánh phát triển chính trước khi sẵn sàng để merge, bạn vẫn có thể đảo ngược merge. Nhưng có một điểm phải nắm được: Một commit merge có một hoặc nhiều hơn một parent (gốc) (thường là 2).
@ -433,7 +486,7 @@ Dòng `-m 1` là để cho biết cần chọn parent thứ nhất` (nhánh mà
Chú ý: Số parent không phải là số commit. Thay vào đó, một commit merge sẽ có một dòng như `Merge: 8e2ce2d 86ac2e7`. Số parent là số số nhận dạng đầu-1 (1-based index) của dòng nay, số nhận dạng đầu tiên là 1 cho parent thứ nhất, thứ 2 là cho parent 2, và tiếp tục như thế. Chú ý: Số parent không phải là số commit. Thay vào đó, một commit merge sẽ có một dòng như `Merge: 8e2ce2d 86ac2e7`. Số parent là số số nhận dạng đầu-1 (1-based index) của dòng nay, số nhận dạng đầu tiên là 1 cho parent thứ nhất, thứ 2 là cho parent 2, và tiếp tục như thế.
<a href="undo-sensitive-commit-push"></a> <a name="undo-sensitive-commit-push"></a>
### Tôi vô tình commit và đẩy các file chứa dữ liệu nhảy cảm ### Tôi vô tình commit và đẩy các file chứa dữ liệu nhảy cảm
Nếu bạn vô tình push lên các file chứa dữ liệu nhạy cảm (mật khẩu, keys, etc.), bạn có thể amend commit trước. Lưu ý rằng khi bạn đã đẩy một commit, bạn nên coi bất kỳ dữ liệu nào đã bị đẩy như đã bị lộ. Các bước này có thể xoá dữ liệu nhạy cảm từ repo công khai (public repo) hoặc bản sao nội bộ, nhưng bạn *không thể* xóa dữ liệu nhạy cảm khỏi các bản sao đã được tải về bởi người khác. Nếu bạn có commit mật khẩu, *hãy thay đổi mật khẩu ngay lập tức*. Nếu bạn đã commit một key, *hãy tạo lại key đó ngay lập tức*. Việc amend commit đã đẩy là không đủ, vì bất kỳ ai cũng có thể đã pull commit chứa dữ liệu nhạy cảm của bạn trong thời gian đấy. Nếu bạn vô tình push lên các file chứa dữ liệu nhạy cảm (mật khẩu, keys, etc.), bạn có thể amend commit trước. Lưu ý rằng khi bạn đã đẩy một commit, bạn nên coi bất kỳ dữ liệu nào đã bị đẩy như đã bị lộ. Các bước này có thể xoá dữ liệu nhạy cảm từ repo công khai (public repo) hoặc bản sao nội bộ, nhưng bạn *không thể* xóa dữ liệu nhạy cảm khỏi các bản sao đã được tải về bởi người khác. Nếu bạn có commit mật khẩu, *hãy thay đổi mật khẩu ngay lập tức*. Nếu bạn đã commit một key, *hãy tạo lại key đó ngay lập tức*. Việc amend commit đã đẩy là không đủ, vì bất kỳ ai cũng có thể đã pull commit chứa dữ liệu nhạy cảm của bạn trong thời gian đấy.
@ -465,7 +518,7 @@ Nếu bạn muốn xóa hoàn toàn toàn bộ tệp (và không giữ tệp t
Nếu bạn đã thực hiện các commit khác (tức là dữ liệu nhạy cảm nằm tại commit trước commit mới nhất), bạn sẽ phải rebase. Nếu bạn đã thực hiện các commit khác (tức là dữ liệu nhạy cảm nằm tại commit trước commit mới nhất), bạn sẽ phải rebase.
<a href="#i-want-to-remove-a-large-file-from-ever-existing-in-repo-history"></a> <a name="remove-large-file-in-repo-history"></a>
### Tôi muốn xóa file to quá để chưa bao giờ xuất hiện trong lịch sử repository ### Tôi muốn xóa file to quá để chưa bao giờ xuất hiện trong lịch sử repository
Nếu file bạn muốn xóa cần bảo mật hay là file chưa thông tin nhạy cảm, xem phần [xóa file chứa thông tin nhạy cảm](#undo-sensitive-commit-push). Nếu file bạn muốn xóa cần bảo mật hay là file chưa thông tin nhạy cảm, xem phần [xóa file chứa thông tin nhạy cảm](#undo-sensitive-commit-push).
@ -539,7 +592,7 @@ Nếu cách này không hiệu quả, bạn sẽ phải push thủ công lịch
``` ```
Một khi lệnh push thành công, dần dần giảm thiểu `<số cục>` cho đến khi một lệnh `git push` bình thường thành công. Một khi lệnh push thành công, dần dần giảm thiểu `<số cục>` cho đến khi một lệnh `git push` bình thường thành công.
<a href="i-need-to-change-the-content-of-a-commit-which-is-not-my-last"></a> <a name="change-content-of-commit-not-my-last"></a>
### Tôi cần thay đổi nội dung của một commit nhưng không phải là cái mới nhất ### Tôi cần thay đổi nội dung của một commit nhưng không phải là cái mới nhất
Giả sử bạn đã có vài (v.d. ba) commit và sau nhận ra là bạn quên mất không cho vào một thứ gì đó hợp hơn với commit đầu tiên. Việc này làm phiền bạn vì mặc dù nếu tiếp tục commit bạn sẽ có lịch sử sạch sẽ nhưng commit của bạn không nguyên chất (những thay đổi liên quan với nhau nên ở cùng một commit). Trong trường hợp như vậy, bạn chắc muốn cho thêm những thay đổi liên quan vào commit mong muốn nhưng không muốn những commit sau tiếp cũng phải sửa theo. Trong trường hợp như vây, `git rebase` có thể cứu bạn. Giả sử bạn đã có vài (v.d. ba) commit và sau nhận ra là bạn quên mất không cho vào một thứ gì đó hợp hơn với commit đầu tiên. Việc này làm phiền bạn vì mặc dù nếu tiếp tục commit bạn sẽ có lịch sử sạch sẽ nhưng commit của bạn không nguyên chất (những thay đổi liên quan với nhau nên ở cùng một commit). Trong trường hợp như vậy, bạn chắc muốn cho thêm những thay đổi liên quan vào commit mong muốn nhưng không muốn những commit sau tiếp cũng phải sửa theo. Trong trường hợp như vây, `git rebase` có thể cứu bạn.
@ -582,8 +635,7 @@ Lệnh trên sẽ giải quyết phần còn lại.
## Staging (sân chuyển tiếp) ## Staging (sân chuyển tiếp)
<a href="#i-want-to-stage-all-tracked-files-and-leave-untracked-files"></a> <a name="stage-tracked-files-and-leave-untracked-files"></a>
### Tôi muốn nâng lên stage tất cả file đang theo dõi và bỏ qua file không theo dõi ### Tôi muốn nâng lên stage tất cả file đang theo dõi và bỏ qua file không theo dõi
```sh ```sh
@ -600,7 +652,7 @@ $ git add -u *.txt
$ git add -u src/ $ git add -u src/
``` ```
<a href="#i-need-to-add-staged-changes-to-the-previous-commit"></a> <a name="add-staged-changes-to-previous-commit"></a>
### Tôi cần cho thêm các thay đổi đang trong stage vào commit trước ### Tôi cần cho thêm các thay đổi đang trong stage vào commit trước
```sh ```sh
@ -631,18 +683,18 @@ $ git add -N filename.x
Sau đó, bạn sẽ cần sử dụng `e` để thủ công thêm dòng. Chạy lệnh `git diff --cached` hoặc Sau đó, bạn sẽ cần sử dụng `e` để thủ công thêm dòng. Chạy lệnh `git diff --cached` hoặc
`git diff --staged` sẽ cho bạn thấy những dòng bạn đã stage so với những dòng vẫn lưu ở local. `git diff --staged` sẽ cho bạn thấy những dòng bạn đã stage so với những dòng vẫn lưu ở local.
<a href="stage-in-two-commits"></a> <a name="stage-in-two-commits"></a>
### Tôi muốn thêm các thay đổi trong một file vào 2 commit khác nhau ### Tôi muốn thêm các thay đổi trong một file vào 2 commit khác nhau
`git add` sẽ thêm toàn bộ file vào một commit. `git add -p` sẽ cho vào chế độ tương tác để chọn những thay đổi bạn muốn thêm vào. `git add` sẽ thêm toàn bộ file vào một commit. `git add -p` sẽ cho vào chế độ tương tác để chọn những thay đổi bạn muốn thêm vào.
<a href="selective-unstage-edits"></a> <a name="selective-unstage-edits"></a>
### Tôi cho lên stage quá nhiều thay đổi, và tôi muốn tách ra thành các commit khác nhau ### Tôi cho lên stage quá nhiều thay đổi, và tôi muốn tách ra thành các commit khác nhau
`git reset -p` sẽ mở chế độ patch và hộp thoại để reset. Việc này sẽ giống như với lệnh `git add -p`, ngoại trừ là việc chọn "yes" sẽ đưa thay đổi khỏi stage, loại trừ nó khỏi commit tiếp đến. `git reset -p` sẽ mở chế độ patch và hộp thoại để reset. Việc này sẽ giống như với lệnh `git add -p`, ngoại trừ là việc chọn "yes" sẽ đưa thay đổi khỏi stage, loại trừ nó khỏi commit tiếp đến.
<a href="unstaging-edits-and-staging-the-unstaged"></a> <a name="unstaging-edits-and-staging-the-unstaged"></a>
### Tôi muốn cho lên stage các chỉnh sửa chưa được stage và khỏi stage các chỉnh sửa đã stage ### Tôi muốn cho lên stage các chỉnh sửa chưa được stage và bỏ khỏi stage các chỉnh sửa đã stage
Phần lớn thời gian, bạn nên hạ tất cả các file đã trên stage và chọn lại những file bạn muốn commit.Nhưng giả sử bạn muốn thay các thay đổi lên và hạ stage, bạn có thể tạo một commit tạm thời, nâng lên stage các thay đổi, rồi stash (cất) nó. Sau đó, reset cái commit tạm thời rồi pop cái stage bạn vừa cất. Phần lớn thời gian, bạn nên hạ tất cả các file đã trên stage và chọn lại những file bạn muốn commit.Nhưng giả sử bạn muốn thay các thay đổi lên và hạ stage, bạn có thể tạo một commit tạm thời, nâng lên stage các thay đổi, rồi stash (cất) nó. Sau đó, reset cái commit tạm thời rồi pop cái stage bạn vừa cất.
@ -657,25 +709,20 @@ $ git stash pop --index 0
GHI CHÚ 1: Lý do để dùng `pop` là để giữ nguyên các thay đổi nhất có thể. GHI CHÚ 1: Lý do để dùng `pop` là để giữ nguyên các thay đổi nhất có thể.
GHI CHÚ 2: Các file đã nâng lên stage sẽ bị hạ nếu không có thêm cờ `--index`. ([Link](https://stackoverflow.com/questions/31595873/git-stash-with-staged-files-does-stash-convert-staged-files-to-unstaged?answertab=active#tab-top) explains why.) GHI CHÚ 2: Các file đã nâng lên stage sẽ bị hạ nếu không có thêm cờ `--index`. ([Link](https://stackoverflow.com/questions/31595873/git-stash-with-staged-files-does-stash-convert-staged-files-to-unstaged?answertab=active#tab-top) explains why.)
## Thay đổi chưa lên sân (Unstaged Edits) <a name="unstage-specific-staged-file"></a>
### Tôi muốn unstage 1 file đã stage cụ thể
<a href="move-unstaged-edits-to-new-branch"></a> Đôi khi chúng tôi có một hoặc nhiều tệp vô tình bị stage và những tệp này chưa được commit trước đó. Để loại bỏ chúng:
### Tôi muốn di chuyển các chỉnh sửa chưa lên stage sang một nhánh mới
```sh ```sh
$ git checkout -b nhánh-mới $ git reset -- <filename>
``` ```
<a href="move-unstaged-edits-to-old-branch"></a> Lệnh trên dẫn đến việc unstage tệp và làm cho nó không bị track.
### Tôi muốn di chuyển các chỉnh sửa chưa stage của tôi đến một nhánh khác đã tồn tại
```sh ## Hủy bỏ những thay đổi (Discarding changes)
$ git stash
$ git checkout nhánh-tồn-tại
$ git stash pop
```
<a href="i-want-to-discard-my-local-uncommitted-changes"></a> <a name="discard-local-uncommitted-changes"></a>
### Tôi muốn bỏ các thay đôi chưa trong commit tại local (đã lên hoặc chưa lên stage) ### Tôi muốn bỏ các thay đôi chưa trong commit tại local (đã lên hoặc chưa lên stage)
Nếu bạn muốn bỏ tất cả các thay đổi đã lên hoặc chưa lên stage tại local của bạn, bạn có thể làm như sau: Nếu bạn muốn bỏ tất cả các thay đổi đã lên hoặc chưa lên stage tại local của bạn, bạn có thể làm như sau:
@ -767,7 +814,7 @@ Khi bạn muốn loại bỏ tất cả các thay đổi chưa commit mà chưa
```sh ```sh
$ git checkout . $ git checkout .
``` ```
<a href="i-want-to-discard-all-my-untracked-files"></a> <a name="discard-all-untracked-files"></a>
### Tôi muốn loại bỏ tất cả các file chưa được theo dõi (track) ### Tôi muốn loại bỏ tất cả các file chưa được theo dõi (track)
Khi bạn muốn loại bỏ tất cả các file chưa được theo dõi Khi bạn muốn loại bỏ tất cả các file chưa được theo dõi
@ -776,16 +823,7 @@ Khi bạn muốn loại bỏ tất cả các file chưa được theo dõi
$ git clean -f $ git clean -f
``` ```
<a href="I-want-to-unstage-specific-staged-file"></a> <a name="unstage-specific-staged-file"></a>
### Tôi muốn hạ khỏi stage một file cụ thể đã stage
Đôi khi, chúng ta có một hoặc nhiều file đã vô tình lên stage và các file này chưa được commit trước đó. Để hạ chúng khỏi stage:
```sh
$ git reset -- <TênFile>
```
Lệnh trên sẽ hạ file khỏi stage và làm nó không được theo dõi (untracked).
## Nhánh ## Nhánh
@ -834,7 +872,7 @@ $ git reset --hard c5bc55a
Xong. Xong.
<a href="discard-local-commits"></a> <a name="discard-local-commits"></a>
### Tôi muốn loại bỏ các commit tại local để nhánh của tôi giống như nhánh trên server ### Tôi muốn loại bỏ các commit tại local để nhánh của tôi giống như nhánh trên server
Kiểm tra rằng bạn chưa push các thay đổi của mình đến server. Kiểm tra rằng bạn chưa push các thay đổi của mình đến server.
@ -855,6 +893,22 @@ Một cách để reset về origin (để có nhánh giống như trên remote)
(my-branch)$ git reset --hard origin/my-branch (my-branch)$ git reset --hard origin/my-branch
``` ```
<a name="move-unstaged-edits-to-new-branch"></a>
### Tôi muốn chuyển những thay đổi chưa lên stage tới nhánh mới
```sh
$ git checkout -b my-branch
```
<a name="move-unstaged-edits-to-old-branch"></a>
### Tôi muốn chuyển những thay đổi chưa lên stage tới nhánh khác đã tạo
```sh
$ git stash
$ git checkout my-branch
$ git stash pop
```
<a name="commit-wrong-branch"></a> <a name="commit-wrong-branch"></a>
### Tôi đã tạo commit lên main thay vì một nhánh mới ### Tôi đã tạo commit lên main thay vì một nhánh mới
@ -975,7 +1029,7 @@ Bây giờ, hãy *cherry-pick* commit cho bug #21 trên đầu của nhánh. Nó
(21)$ git cherry-pick e3851e8 (21)$ git cherry-pick e3851e8
``` ```
Tại thời điểm này, có khả năng có thể có xung đột hợp (merge conflicts). Hãy xem phần [**There were conflicts**](#merge-conflict) trong [phần interactive rebasing ở trên](#interactive-rebase) để làm thế nào giải quyết xung đột hợp. Tại thời điểm này, có khả năng có thể có xung đột hợp (merge conflicts). Hãy xem phần [**Có một vài xung đột**](#merge-conflict) trong [phần interactive rebasing ở trên](#interactive-rebase) để làm thế nào giải quyết xung đột hợp.
Bây giờ chúng ta hãy tạo một nhánh mới cho bug # 14, cũng dựa trên nhánh main: Bây giờ chúng ta hãy tạo một nhánh mới cho bug # 14, cũng dựa trên nhánh main:
@ -1002,7 +1056,7 @@ $ git fetch -p upstream
upstream` là remote bạn muốn fetch (gọi) về. upstream` là remote bạn muốn fetch (gọi) về.
<a name='restore-a-deleted-branch'></a> <a name="restore-a-deleted-branch"></a>
### Tôi vô tình xóa nhánh của tôi ### Tôi vô tình xóa nhánh của tôi
Nếu bạn thường xuyên push lên remote, bạn sẽ an toàn phần lớn thời gian. Nhưng đôi khi bạn có thể sẽ xóa các nhánh của bạn. Giả sử chúng ta tạo một nhánh và tạo một tệp mới: Nếu bạn thường xuyên push lên remote, bạn sẽ an toàn phần lớn thời gian. Nhưng đôi khi bạn có thể sẽ xóa các nhánh của bạn. Giả sử chúng ta tạo một nhánh và tạo một tệp mới:
@ -1126,7 +1180,7 @@ Giả sử bạn muốn xoá tất cả các nhánh bắt đầu với `fix/`:
(main)$ git push origin :tên_cũ tên_mới (main)$ git push origin :tên_cũ tên_mới
``` ```
<a name="i-want-to-checkout-to-a-remote-branch-that-someone-else-is-working-on"></a> <a name="working-on-checkout-remote-branch"></a>
### Tôi muốn checkout đến một nhánh remote mà người khác đang làm việc trên đó ### Tôi muốn checkout đến một nhánh remote mà người khác đang làm việc trên đó
Đầu tiên, fetch tất cả nhánh từ remote: Đầu tiên, fetch tất cả nhánh từ remote:
@ -1165,7 +1219,7 @@ Với chế độ `upstream` và `simple` (mặc định trong Git 2.0) của c
$ git push $ git push
``` ```
Các hành vi của các chế độ khác của `git push` được mô tả trong [doc cho `push.default`](https://git-scm.com/docs/git-config#git-config-pushdefault). Các hành vi của các chế độ khác của `git push` được mô tả trong [doc cho `push.default`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushdefault).
### Tôi muốn thiết lập một nhánh remote làm upstream (luồng trước) cho một nhánh local ### Tôi muốn thiết lập một nhánh remote làm upstream (luồng trước) cho một nhánh local
@ -1183,7 +1237,7 @@ $ git branch -u [remotename]/[branch]
$ git branch -u [remotename]/[branch] [local-branch] $ git branch -u [remotename]/[branch] [local-branch]
``` ```
<a name="i-want-to-set-my-HEAD-to-track-the-default-remote-branch"></a> <a name="head-to-track-remote-branch"></a>
### Tôi muốn để HEAD của tôi dõi theo nhánh mặc định của remote ### Tôi muốn để HEAD của tôi dõi theo nhánh mặc định của remote
Bằng cách kiểm tra các nhánh remote của bạn, bạn có thể thấy nhánh remote nào mà HEAD của bạn đang theo dõi. Trong một số trường hợp, có thể đấy không phải là nhánh mong muốn. Bằng cách kiểm tra các nhánh remote của bạn, bạn có thể thấy nhánh remote nào mà HEAD của bạn đang theo dõi. Trong một số trường hợp, có thể đấy không phải là nhánh mong muốn.
@ -1211,7 +1265,7 @@ Bạn đã thực hiện các thay đổi chưa được commit và nhận ra b
(correct_branch)$ git stash apply (correct_branch)$ git stash apply
``` ```
<a name="i-want-to-split-a-branch-into-two"></a> <a name="split-branch-into-two"></a>
### Tôi muốn tách một nhánh thành hai ### Tôi muốn tách một nhánh thành hai
Bạn đã tạo rất nhiều commit trên một nhành và bây giờ bạn muốn tách nhánh ra thành hai, một nhánh kết thúc với một commit cũ, và một nhánh với tất cả các thay đổi. Bạn đã tạo rất nhiều commit trên một nhành và bây giờ bạn muốn tách nhánh ra thành hai, một nhánh kết thúc với một commit cũ, và một nhánh với tất cả các thay đổi.
@ -1229,7 +1283,7 @@ Nếu bạn trước đó đã push nhánh gốc lên remote, bạn sẽ cần p
## Rebasing và Merging ## Rebasing và Merging
<a name="undo-rebase"></a> <a name="undo-rebase"></a>
### Tôi muốn đảo ngược rebase/merge ### Tôi muốn hoàn tác rebase/merge
Bạn có thể đã merge hoặc rebase nhánh hiện tại của bạn với một nhánh sai hoặc bạn không thể tìm ra cách hoàn thành quá trình rebase/merge. Git lưu con trỏ original HEAD trong một variable (biến) được gọi là ORIG_HEAD trước khi chạy các hành động nguy hiểm, vì vậy bạn có thể dễ dàng khôi phục lại trạng thái trước khi rebase/merge. Bạn có thể đã merge hoặc rebase nhánh hiện tại của bạn với một nhánh sai hoặc bạn không thể tìm ra cách hoàn thành quá trình rebase/merge. Git lưu con trỏ original HEAD trong một variable (biến) được gọi là ORIG_HEAD trước khi chạy các hành động nguy hiểm, vì vậy bạn có thể dễ dàng khôi phục lại trạng thái trước khi rebase/merge.
@ -1453,7 +1507,7 @@ Nếu bạn muốn giữ phiên bản code của một nhánh, bạn có thể s
``` ```
- Khi *đang merge*, sử dụng `--ours` để giữ các thay đổi từ nhánh local, hoặc `--theirs` để giữ các thay đổi từ nhánh khác. - Khi *đang merge*, sử dụng `--ours` để giữ các thay đổi từ nhánh local, hoặc `--theirs` để giữ các thay đổi từ nhánh khác.
- Khi *đang rebase*, sử dụng `--theirs` để giữ các thay đổi từ nhánh local, hoặc `--ours` để giữ các thay đổi từ nhánh khác. Để hiểu giải thích về sự hoán đổi này, hãy xem [ghi chú này trong tài liệu Git](https://git-scm.com/docs/git-rebase#git-rebase---merge). - Khi *đang rebase*, sử dụng `--theirs` để giữ các thay đổi từ nhánh local, hoặc `--ours` để giữ các thay đổi từ nhánh khác. Để hiểu giải thích về sự hoán đổi này, hãy xem [ghi chú này trong tài liệu Git](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---merge).
Nếu việc merge phức tạp hơn, bạn có thể sử dụng trình chỉnh sửa khác biệt trực quan (visual diff editor): Nếu việc merge phức tạp hơn, bạn có thể sử dụng trình chỉnh sửa khác biệt trực quan (visual diff editor):
@ -1571,7 +1625,7 @@ Các cờ thường dùng:
* `--reverse` in theo thứ tự ngược lại, có nghĩa là hiển thị commit đầu tiên đã thực hiện thay đổi. * `--reverse` in theo thứ tự ngược lại, có nghĩa là hiển thị commit đầu tiên đã thực hiện thay đổi.
<a name="i-want-to-find-by-author-committer"></a> <a name="find-by-committer"></a>
### Tôi muốn tìm tác giả hoặc người commit ### Tôi muốn tìm tác giả hoặc người commit
Để tìm tất cả commit từ tác giả hoặc người commit bạn có thể sử dụng: Để tìm tất cả commit từ tác giả hoặc người commit bạn có thể sử dụng:
@ -1603,7 +1657,7 @@ Trong khi sử dụng ký tự đại diện bất kỳ, sẽ hữu ích hơn kh
$ git log --name-status -- **/*.js $ git log --name-status -- **/*.js
``` ```
<a name="#i-want-to-view-the-commit-history-for-a-specific-function"></a> <a name="view-commit-history-for-specific-function"></a>
### Tôi muốn xem lịch sử commit của một function (chức năng) cụ thể ### Tôi muốn xem lịch sử commit của một function (chức năng) cụ thể
Để truy tìm lịch sử tiến hóa của một function là dùng lệnh: Để truy tìm lịch sử tiến hóa của một function là dùng lệnh:
@ -1734,7 +1788,7 @@ $ git push origin refs/tags/<tag-name>
## Tracking (Theo dõi) các file ## Tracking (Theo dõi) các file
<a href="i-want-to-change-a-file-names-capitalization-without-changing-the-contents-of-the-file"></a> <a name="change-file-name-capitalization-without-changing-contents"></a>
### Tôi muốn thay đổi cách viết hoa của tên tệp mà không thay đổi nội dung của tệp ### Tôi muốn thay đổi cách viết hoa của tên tệp mà không thay đổi nội dung của tệp
```sh ```sh
@ -1748,7 +1802,7 @@ $ git push origin refs/tags/<tag-name>
(main)$ git reset --hard origin/main (main)$ git reset --hard origin/main
``` ```
<a href="remove-from-git"></a> <a name="remove-from-git"></a>
### Tôi muốn xóa một tệp khỏi Git nhưng vẫn giữ tệp ### Tôi muốn xóa một tệp khỏi Git nhưng vẫn giữ tệp
```sh ```sh
@ -2039,6 +2093,7 @@ function Squash-Commits {
* [git-town](https://github.com/Originate/git-town) - Hỗ trợ luồng làm việc Git chung, tầm nâng cao! http://www.git-town.com * [git-town](https://github.com/Originate/git-town) - Hỗ trợ luồng làm việc Git chung, tầm nâng cao! http://www.git-town.com
## GUI Clients ## GUI Clients
* [GitKraken](https://www.gitkraken.com/) - Client sang trọng cho Windows, Mac & Linux * [GitKraken](https://www.gitkraken.com/) - Client sang trọng cho Windows, Mac & Linux
* [git-cola](https://git-cola.github.io/) - Git client khác cho Windows và OS X * [git-cola](https://git-cola.github.io/) - Git client khác cho Windows và OS X
* [GitUp](https://github.com/git-up/GitUp) - Một GUI mới mẻ mà có một số cách rất quan tâm để giải quyết các việc khó chịu của Git * [GitUp](https://github.com/git-up/GitUp) - Một GUI mới mẻ mà có một số cách rất quan tâm để giải quyết các việc khó chịu của Git

View File

@ -110,7 +110,7 @@
$ git log -n1 -p $ git log -n1 -p
``` ```
<a name="#i-wrote-the-wrong-thing-in-a-commit-message"></a> <a name="wrong-thing-in-commit-message"></a>
### 我的提交信息(commit message)写错了 ### 我的提交信息(commit message)写错了
如果你的提交信息(commit message)写错了且这次提交(commit)还没有推(push), 你可以通过下面的方法来修改提交信息(commit message): 如果你的提交信息(commit message)写错了且这次提交(commit)还没有推(push), 你可以通过下面的方法来修改提交信息(commit message):
@ -137,7 +137,7 @@ $ git commit --amend --author "New Authorname <authoremail@mydomain.com>"
如果你需要修改所有历史, 参考 'git filter-branch'的指南页. 如果你需要修改所有历史, 参考 'git filter-branch'的指南页.
<a href="#i-want-to-remove-a-file-from-a-commit"></a> <a name="remove-file-from-commit"></a>
### 我想从一个提交(commit)里移除一个文件 ### 我想从一个提交(commit)里移除一个文件
通过下面的方法,从一个提交(commit)里移除一个文件: 通过下面的方法,从一个提交(commit)里移除一个文件:
@ -180,7 +180,7 @@ $ git push -f [remote] [branch]
或者做一个 [交互式rebase](#interactive-rebase) 删除那些你想要删除的提交(commit)里所对应的行。 或者做一个 [交互式rebase](#interactive-rebase) 删除那些你想要删除的提交(commit)里所对应的行。
<a name="#force-push"></a> <a name="force-push"></a>
### 我尝试推一个修正后的提交(amended commit)到远程,但是报错: ### 我尝试推一个修正后的提交(amended commit)到远程,但是报错:
```sh ```sh
@ -201,7 +201,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
一般来说, **要避免强推**. 最好是创建和推(push)一个新的提交(commit),而不是强推一个修正后的提交。后者会使那些与该分支或该分支的子分支工作的开发者,在源历史中产生冲突。 一般来说, **要避免强推**. 最好是创建和推(push)一个新的提交(commit),而不是强推一个修正后的提交。后者会使那些与该分支或该分支的子分支工作的开发者,在源历史中产生冲突。
<a href="undo-git-reset-hard"></a> <a name="undo-git-reset-hard"></a>
### 我意外的做了一次硬重置(hard reset),我想找回我的内容 ### 我意外的做了一次硬重置(hard reset),我想找回我的内容
如果你意外的做了 `git reset --hard`, 你通常能找回你的提交(commit), 因为Git对每件事都会有日志且都会保存几天。 如果你意外的做了 `git reset --hard`, 你通常能找回你的提交(commit), 因为Git对每件事都会有日志且都会保存几天。
@ -220,7 +220,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
## 暂存(Staging) ## 暂存(Staging)
<a href="#i-need-to-add-staged-changes-to-the-previous-commit"></a> <a name="add-staged-changes-to-previous-commit"></a>
### 我需要把暂存的内容添加到上一次的提交(commit) ### 我需要把暂存的内容添加到上一次的提交(commit)
```sh ```sh
@ -245,12 +245,12 @@ $ git add -N filename.x
然后, 你需要用 `e` 选项来手动选择需要添加的行,执行 `git diff --cached` 将会显示哪些行暂存了哪些行只是保存在本地了。 然后, 你需要用 `e` 选项来手动选择需要添加的行,执行 `git diff --cached` 将会显示哪些行暂存了哪些行只是保存在本地了。
<a href="stage-in-two-commits"></a> <a name="stage-in-two-commits"></a>
### 我想把在一个文件里的变化(changes)加到两个提交(commit)里 ### 我想把在一个文件里的变化(changes)加到两个提交(commit)里
`git add` 会把整个文件加入到一个提交. `git add -p` 允许交互式的选择你想要提交的部分. `git add` 会把整个文件加入到一个提交. `git add -p` 允许交互式的选择你想要提交的部分.
<a href="unstaging-edits-and-staging-the-unstaged"></a> <a name="unstaging-edits-and-staging-the-unstaged"></a>
### 我想把暂存的内容变成未暂存,把未暂存的内容暂存起来 ### 我想把暂存的内容变成未暂存,把未暂存的内容暂存起来
多数情况下你应该将所有的内容变为未暂存然后再选择你想要的内容进行commit。 多数情况下你应该将所有的内容变为未暂存然后再选择你想要的内容进行commit。
@ -269,14 +269,14 @@ $ git stash pop --index 0
## 未暂存(Unstaged)的内容 ## 未暂存(Unstaged)的内容
<a href="move-unstaged-edits-to-new-branch"></a> <a name="move-unstaged-edits-to-new-branch"></a>
### 我想把未暂存的内容移动到一个新分支 ### 我想把未暂存的内容移动到一个新分支
```sh ```sh
$ git checkout -b my-branch $ git checkout -b my-branch
``` ```
<a href="move-unstaged-edits-to-old-branch"></a> <a name="move-unstaged-edits-to-old-branch"></a>
### 我想把未暂存的内容移动到另一个已存在的分支 ### 我想把未暂存的内容移动到另一个已存在的分支
```sh ```sh
@ -285,7 +285,7 @@ $ git checkout my-branch
$ git stash pop $ git stash pop
``` ```
<a href="i-want-to-discard-my-local-uncommitted-changes"></a> <a name="discard-local-uncommitted-changes"></a>
### 我想丢弃本地未提交的变化(uncommitted changes) ### 我想丢弃本地未提交的变化(uncommitted changes)
如果你只是想重置源(origin)和你本地(local)之间的一些提交(commit),你可以: 如果你只是想重置源(origin)和你本地(local)之间的一些提交(commit),你可以:
@ -307,7 +307,7 @@ $ git stash pop
$ git reset filename $ git reset filename
``` ```
<a href="i-want-to-discard-specific-unstaged-changes"></a> <a name="discard-specific-unstaged-changes"></a>
### 我想丢弃某些未暂存的内容 ### 我想丢弃某些未暂存的内容
如果你想丢弃工作拷贝中的一部分内容,而不是全部。 如果你想丢弃工作拷贝中的一部分内容,而不是全部。
@ -357,7 +357,7 @@ $ git reset --hard c5bc55a
完成。 完成。
<a href="discard-local-commits"></a> <a name="discard-local-commits"></a>
### 我想扔掉本地的提交(commit),以便我的分支与远程的保持一致 ### 我想扔掉本地的提交(commit),以便我的分支与远程的保持一致
先确认你没有推(push)你的内容到远程。 先确认你没有推(push)你的内容到远程。
@ -520,7 +520,7 @@ HEAD is now at a13b85e
$ git fetch -p $ git fetch -p
``` ```
<a name='restore-a-deleted-branch'></a> <a name="restore-a-deleted-branch"></a>
### 我不小心删除了我的分支 ### 我不小心删除了我的分支
如果你定期推送到远程, 多数情况下应该是安全的,但有些时候还是可能删除了还没有推到远程的分支。 让我们先创建一个分支和一个新的文件: 如果你定期推送到远程, 多数情况下应该是安全的,但有些时候还是可能删除了还没有推到远程的分支。 让我们先创建一个分支和一个新的文件:
@ -590,7 +590,7 @@ README.md foo.txt
看! 我们把删除的文件找回来了。 Git的 `reflog` 在rebasing出错的时候也是同样有用的。 看! 我们把删除的文件找回来了。 Git的 `reflog` 在rebasing出错的时候也是同样有用的。
<a name="i-want-to-delete-a-branch"></a> <a name="delete-branch"></a>
### 我想删除一个分支 ### 我想删除一个分支
删除一个远程分支: 删除一个远程分支:
@ -611,7 +611,7 @@ README.md foo.txt
(main)$ git branch -D my-branch (main)$ git branch -D my-branch
``` ```
<a name="i-want-to-checkout-to-a-remote-branch-that-someone-else-is-working-on"></a> <a name="working-on-checkout-remote-branch"></a>
### 我想从别人正在工作的远程分支签出(checkout)一个分支 ### 我想从别人正在工作的远程分支签出(checkout)一个分支
首先, 从远程拉取(fetch) 所有分支: 首先, 从远程拉取(fetch) 所有分支:
@ -920,7 +920,7 @@ $ git stash apply "stash@{n}"
$ git stash apply "stash@{2.hours.ago}" $ git stash apply "stash@{2.hours.ago}"
``` ```
<a href="stage-and-keep-unstaged"></a> <a name="stage-and-keep-unstaged"></a>
### 暂存时保留未暂存的内容 ### 暂存时保留未暂存的内容
你需要手动create一个`stash commit` 然后使用`git stash store` 你需要手动create一个`stash commit` 然后使用`git stash store`
@ -980,14 +980,14 @@ $ git update-ref refs/tags/<tag_name> <hash>
## 跟踪文件(Tracking Files) ## 跟踪文件(Tracking Files)
<a href="i-want-to-change-a-file-names-capitalization-without-changing-the-contents-of-the-file"></a> <a name="change-file-name-capitalization-without-changing-contents"></a>
### 我只想改变一个文件名字的大小写,而不修改内容 ### 我只想改变一个文件名字的大小写,而不修改内容
```sh ```sh
(main)$ git mv --force myfile MyFile (main)$ git mv --force myfile MyFile
``` ```
<a href="remove-from-git"></a> <a name="remove-from-git"></a>
### 我想从Git删除一个文件但保留该文件 ### 我想从Git删除一个文件但保留该文件
```sh ```sh
@ -1039,7 +1039,7 @@ $ git config --global credential.helper 'cache --timeout=3600'
# Set the cache to timeout after 1 hour (setting is in seconds) # Set the cache to timeout after 1 hour (setting is in seconds)
``` ```
<a href="#ive-no-idea-what-i-did-wrong"></a> <a name="ive-no-idea-what-i-did-wrong"></a>
## 我不知道我做错了些什么 ## 我不知道我做错了些什么
你把事情搞砸了:你 `重置(reset)` 了一些东西, 或者你合并了错误的分支, 亦或你强推了后找不到你自己的提交(commit)了。有些时候, 你一直都做得很好, 但你想回到以前的某个状态。 你把事情搞砸了:你 `重置(reset)` 了一些东西, 或者你合并了错误的分支, 亦或你强推了后找不到你自己的提交(commit)了。有些时候, 你一直都做得很好, 但你想回到以前的某个状态。

View File

@ -103,18 +103,41 @@
- [貯存時附加訊息](#%E8%B2%AF%E5%AD%98%E6%99%82%E9%99%84%E5%8A%A0%E8%A8%8A%E6%81%AF) - [貯存時附加訊息](#%E8%B2%AF%E5%AD%98%E6%99%82%E9%99%84%E5%8A%A0%E8%A8%8A%E6%81%AF)
- [套用指定貯存](#%E5%A5%97%E7%94%A8%E6%8C%87%E5%AE%9A%E8%B2%AF%E5%AD%98) - [套用指定貯存](#%E5%A5%97%E7%94%A8%E6%8C%87%E5%AE%9A%E8%B2%AF%E5%AD%98)
- [貯存時保留未暫存的內容](#%E8%B2%AF%E5%AD%98%E6%99%82%E4%BF%9D%E7%95%99%E6%9C%AA%E6%9A%AB%E5%AD%98%E7%9A%84%E5%85%A7%E5%AE%B9) - [貯存時保留未暫存的內容](#%E8%B2%AF%E5%AD%98%E6%99%82%E4%BF%9D%E7%95%99%E6%9C%AA%E6%9A%AB%E5%AD%98%E7%9A%84%E5%85%A7%E5%AE%B9)
- [雜項](#%E9%9B%9C%E9%A0%85) - [尋找](#%E5%B0%8B%E6%89%BE)
- [我想找到引入特定字串的提交](#%E6%88%91%E6%83%B3%E6%89%BE%E5%88%B0%E5%BC%95%E5%85%A5%E7%89%B9%E5%AE%9A%E5%AD%97%E4%B8%B2%E7%9A%84%E6%8F%90%E4%BA%A4)
- [我想找到特定作者/提交者的提交](#%E6%88%91%E6%83%B3%E6%89%BE%E5%88%B0%E7%89%B9%E5%AE%9A%E4%BD%9C%E8%80%85%EF%BC%8F%E6%8F%90%E4%BA%A4%E8%80%85%E7%9A%84%E6%8F%90%E4%BA%A4)
- [我想找到包含特定檔案的提交](#%E6%88%91%E6%83%B3%E6%89%BE%E5%88%B0%E5%8C%85%E5%90%AB%E7%89%B9%E5%AE%9A%E6%AA%94%E6%A1%88%E7%9A%84%E6%8F%90%E4%BA%A4)
- [我想找到特定函式的歷史記錄](#%E6%88%91%E6%83%B3%E6%89%BE%E5%88%B0%E7%89%B9%E5%AE%9A%E5%87%BD%E5%BC%8F%E7%9A%84%E6%AD%B7%E5%8F%B2%E8%A8%98%E9%8C%84)
- [我想找到引用特定提交的標籤](#%E6%88%91%E6%83%B3%E6%89%BE%E5%88%B0%E5%BC%95%E7%94%A8%E7%89%B9%E5%AE%9A%E6%8F%90%E4%BA%A4%E7%9A%84%E6%A8%99%E7%B1%A4)
- [子模組](#%E5%AD%90%E6%A8%A1%E7%B5%84)
- [複製所有子模組](#%E8%A4%87%E8%A3%BD%E6%89%80%E6%9C%89%E5%AD%90%E6%A8%A1%E7%B5%84) - [複製所有子模組](#%E8%A4%87%E8%A3%BD%E6%89%80%E6%9C%89%E5%AD%90%E6%A8%A1%E7%B5%84)
- [移除子模組](#%E7%A7%BB%E9%99%A4%E5%AD%90%E6%A8%A1%E7%B5%84)
- [雜項](#%E9%9B%9C%E9%A0%85)
- [從另一個分支拷貝檔案](#%E5%BE%9E%E5%8F%A6%E4%B8%80%E5%80%8B%E5%88%86%E6%94%AF%E6%8B%B7%E8%B2%9D%E6%AA%94%E6%A1%88)
- [恢復刪除的檔案](#%E6%81%A2%E5%BE%A9%E5%88%AA%E9%99%A4%E7%9A%84%E6%AA%94%E6%A1%88)
- [刪除標籤](#%E5%88%AA%E9%99%A4%E6%A8%99%E7%B1%A4) - [刪除標籤](#%E5%88%AA%E9%99%A4%E6%A8%99%E7%B1%A4)
- [恢復已刪除標籤](#%E6%81%A2%E5%BE%A9%E5%B7%B2%E5%88%AA%E9%99%A4%E6%A8%99%E7%B1%A4) - [恢復已刪除標籤](#%E6%81%A2%E5%BE%A9%E5%B7%B2%E5%88%AA%E9%99%A4%E6%A8%99%E7%B1%A4)
- [已刪除修補檔](#%E5%B7%B2%E5%88%AA%E9%99%A4%E4%BF%AE%E8%A3%9C%E6%AA%94) - [已刪除修補檔](#%E5%B7%B2%E5%88%AA%E9%99%A4%E4%BF%AE%E8%A3%9C%E6%AA%94)
- [將版本庫導出為 Zip 檔](#%E5%B0%87%E7%89%88%E6%9C%AC%E5%BA%AB%E5%B0%8E%E5%87%BA%E7%82%BA-zip-%E6%AA%94)
- [推送有相同名稱的分支與標籤](#%E6%8E%A8%E9%80%81%E6%9C%89%E7%9B%B8%E5%90%8C%E5%90%8D%E7%A8%B1%E7%9A%84%E5%88%86%E6%94%AF%E8%88%87%E6%A8%99%E7%B1%A4)
- [追蹤檔案](#%E8%BF%BD%E8%B9%A4%E6%AA%94%E6%A1%88) - [追蹤檔案](#%E8%BF%BD%E8%B9%A4%E6%AA%94%E6%A1%88)
- [我只想改變一個檔案名的大小寫,而不修改內容](#%E6%88%91%E5%8F%AA%E6%83%B3%E6%94%B9%E8%AE%8A%E4%B8%80%E5%80%8B%E6%AA%94%E6%A1%88%E5%90%8D%E5%AD%97%E7%9A%84%E5%A4%A7%E5%B0%8F%E5%AF%AB%E8%80%8C%E4%B8%8D%E4%BF%AE%E6%94%B9%E5%85%A7%E5%AE%B9) - [我只想改變一個檔案名的大小寫,而不修改內容](#%E6%88%91%E5%8F%AA%E6%83%B3%E6%94%B9%E8%AE%8A%E4%B8%80%E5%80%8B%E6%AA%94%E6%A1%88%E5%90%8D%E7%A8%B1%E7%9A%84%E5%A4%A7%E5%B0%8F%E5%AF%AB%E8%80%8C%E4%B8%8D%E4%BF%AE%E6%94%B9%E5%85%A7%E5%AE%B9)
- [我想從 Git 刪除一個檔案,但保留該檔案](#%E6%88%91%E6%83%B3%E5%BE%9E-git-%E5%88%AA%E9%99%A4%E4%B8%80%E5%80%8B%E6%AA%94%E6%A1%88%E4%BD%86%E4%BF%9D%E7%95%99%E8%A9%B2%E6%AA%94%E6%A1%88) - [我想在拉取時覆蓋本機檔案](#%E6%88%91%E6%83%B3%E5%9C%A8%E6%8B%89%E5%8F%96%E6%99%82%E8%A6%86%E8%93%8B%E6%9C%AC%E6%A9%9F%E6%AA%94%E6%A1%88)
- [我想將檔案從 Git 移除,但保留檔案](#%E6%88%91%E6%83%B3%E5%B0%87%E6%AA%94%E6%A1%88%E5%BE%9E-git-%E7%A7%BB%E9%99%A4%E4%BD%86%E4%BF%9D%E7%95%99%E6%AA%94%E6%A1%88)
- [我想將特定檔案還原至某個修訂版](#%E6%88%91%E6%83%B3%E5%B0%87%E7%89%B9%E5%AE%9A%E6%AA%94%E6%A1%88%E9%82%84%E5%8E%9F%E8%87%B3%E6%9F%90%E5%80%8B%E4%BF%AE%E8%A8%82%E7%89%88)
- [我想列出提交或分支之間特定檔案的差異](#%E6%88%91%E6%83%B3%E5%88%97%E5%87%BA%E6%8F%90%E4%BA%A4%E6%88%96%E5%88%86%E6%94%AF%E4%B9%8B%E9%96%93%E7%89%B9%E5%AE%9A%E6%AA%94%E6%A1%88%E7%9A%84%E5%B7%AE%E7%95%B0)
- [我想 Git 忽略特定檔案的更動](#%E6%88%91%E6%83%B3-git-%E5%BF%BD%E7%95%A5%E7%89%B9%E5%AE%9A%E6%AA%94%E6%A1%88%E7%9A%84%E6%9B%B4%E5%8B%95)
- [用 Git 除錯](#%E7%94%A8-git-%E9%99%A4%E9%8C%AF)
- [組態](#%E7%B5%84%E6%85%8B) - [組態](#%E7%B5%84%E6%85%8B)
- [我想為 Git 命令設定別名](#%E6%88%91%E6%83%B3%E7%82%BA-git-%E5%91%BD%E4%BB%A4%E8%A8%AD%E5%AE%9A%E5%88%A5%E5%90%8D) - [我想為 Git 命令設定別名](#%E6%88%91%E6%83%B3%E7%82%BA-git-%E5%91%BD%E4%BB%A4%E8%A8%AD%E5%AE%9A%E5%88%A5%E5%90%8D)
- [我想將空目錄加入到版本庫](#%E6%88%91%E6%83%B3%E5%B0%87%E7%A9%BA%E7%9B%AE%E9%8C%84%E5%8A%A0%E5%85%A5%E5%88%B0%E7%89%88%E6%9C%AC%E5%BA%AB)
- [我想快取一個版本庫的使用者名稱和密碼](#%E6%88%91%E6%83%B3%E5%BF%AB%E5%8F%96%E4%B8%80%E5%80%8B%E7%89%88%E6%9C%AC%E5%BA%AB%E7%9A%84%E4%BD%BF%E7%94%A8%E8%80%85%E5%90%8D%E7%A8%B1%E5%92%8C%E5%AF%86%E7%A2%BC) - [我想快取一個版本庫的使用者名稱和密碼](#%E6%88%91%E6%83%B3%E5%BF%AB%E5%8F%96%E4%B8%80%E5%80%8B%E7%89%88%E6%9C%AC%E5%BA%AB%E7%9A%84%E4%BD%BF%E7%94%A8%E8%80%85%E5%90%8D%E7%A8%B1%E5%92%8C%E5%AF%86%E7%A2%BC)
- [我想 Git 忽略權限與檔案模式更動](#%E6%88%91%E6%83%B3-git-%E5%BF%BD%E7%95%A5%E6%AC%8A%E9%99%90%E8%88%87%E6%AA%94%E6%A1%88%E6%A8%A1%E5%BC%8F%E6%9B%B4%E5%8B%95)
- [我想設定全域使用者資訊](#%E6%88%91%E6%83%B3%E8%A8%AD%E5%AE%9A%E5%85%A8%E5%9F%9F%E4%BD%BF%E7%94%A8%E8%80%85%E8%B3%87%E8%A8%8A)
- [我不知道我做錯了什麼](#%E6%88%91%E4%B8%8D%E7%9F%A5%E9%81%93%E6%88%91%E5%81%9A%E9%8C%AF%E4%BA%86%E4%BB%80%E9%BA%BC) - [我不知道我做錯了什麼](#%E6%88%91%E4%B8%8D%E7%9F%A5%E9%81%93%E6%88%91%E5%81%9A%E9%8C%AF%E4%BA%86%E4%BB%80%E9%BA%BC)
- [Git 快捷命令](#git-%E5%BF%AB%E6%8D%B7%E5%91%BD%E4%BB%A4)
- [Git Bash](#git-bash)
- [Windows 上的 PowerShell](#windows-%E4%B8%8A%E7%9A%84-powershell)
- [其他資源](#%E5%85%B6%E4%BB%96%E8%B3%87%E6%BA%90) - [其他資源](#%E5%85%B6%E4%BB%96%E8%B3%87%E6%BA%90)
- [書籍](#%E6%9B%B8%E7%B1%8D) - [書籍](#%E6%9B%B8%E7%B1%8D)
- [教學](#%E6%95%99%E5%AD%B8) - [教學](#%E6%95%99%E5%AD%B8)
@ -904,7 +927,7 @@ HEAD is now at a13b85e
(21)$ git cherry-pick e3851e8 (21)$ git cherry-pick e3851e8
``` ```
這可能會造成衝突,參見〈[互動式重定基底](#interactive-rebase)・[衝突](#merge-conflict)〉來解決衝突。 這可能會造成衝突,參見〈[互動式重定基底可能出現的問題](#%E4%BA%92%E5%8B%95%E5%BC%8F%E9%87%8D%E5%AE%9A%E5%9F%BA%E5%BA%95%E5%8F%AF%E8%83%BD%E5%87%BA%E7%8F%BE%E7%9A%84%E5%95%8F%E9%A1%8C)・[衝突](#%E8%A1%9D%E7%AA%81)〉來解決衝突。
同樣地,為 `5ea5173` 也創建一個分支,並把提交揀選到其上: 同樣地,為 `5ea5173` 也創建一個分支,並把提交揀選到其上:
@ -1078,7 +1101,7 @@ $ git push -u [遠端] HEAD
$ git push $ git push
``` ```
`git push` 其他模式的行為參見 [`push.default` 的文件](https://git-scm.com/docs/git-config#git-config-pushdefault)。 `git push` 其他模式的行為參見 [`push.default` 的文件](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushdefault)。
### 我想設定本機分支的上游 ### 我想設定本機分支的上游
@ -1368,7 +1391,7 @@ $ git checkout --ours README.md
* *合併*時,`--ours` 代表保留本機分支的更動,`--theirs` 則是另一個分支的更動。 * *合併*時,`--ours` 代表保留本機分支的更動,`--theirs` 則是另一個分支的更動。
* *重定基底*時,`--theirs` 代表保留本機分支的更動,`--ours` 則是另一個分支的更動。 * *重定基底*時,`--theirs` 代表保留本機分支的更動,`--ours` 則是另一個分支的更動。
關於為什麼互換了,參見 [Git 文件的此註記](https://git-scm.com/docs/git-rebase#git-rebase---merge)。 關於為什麼互換了,參見 [Git 文件的此註記](https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---merge)。
有時候衝突非常複雜,你可以使用可視化差異編輯器: 有時候衝突非常複雜,你可以使用可視化差異編輯器:
@ -1401,7 +1424,7 @@ $ git checkout --ours README.md
$ git stash $ git stash
``` ```
可以使用 `-u` 選項排除一些檔案: 也貯存未追蹤的檔案:
```sh ```sh
$ git stash -u $ git stash -u
@ -1437,7 +1460,7 @@ $ git stash push -m <message>
### 套用指定貯存 ### 套用指定貯存
可以先列出擁有的貯存: 先列出貯存:
```sh ```sh
$ git stash list $ git stash list
@ -1464,7 +1487,63 @@ $ git stash create
$ git stash store -m "commit-message" CREATED_SHA1 $ git stash store -m "commit-message" CREATED_SHA1
``` ```
## 雜項 ## 尋找
### 我想找到引入特定字串的提交
```sh
$ git log -S [要尋找的字串]
```
常見的選項:
* `--source` 顯示引用名稱。
* `--all` 尋找每個分支。
* `--reverse` 以相反順序印出,即第一個為最早如此變更的提交。
### 我想找到特定作者/提交者的提交
尋找特定作者/提交者的提交:
```sh
$ git log --author=[名字或 email]
$ git log --committer=[名字或 email]
```
注意作者與提交者並不相同,`--author` 是寫下程式碼的人,`--committer` 則是提交程式碼的人。
### 我想找到包含特定檔案的提交
```sh
$ git log -- [檔案路徑]
```
也可以在檔案路徑中使用萬用字元,如:
```sh
$ git log -- **/*.js
```
使用萬用字元時,以 `--name-status` 列出提交的檔案會有幫助:
```sh
$ git log --name-status -- **/*.js
```
### 我想找到特定函式的歷史記錄
```sh
$ git log -L :[函式名稱]:[檔案路徑]
```
也可以結合其他 `git log` 選項使用,例如[修訂版範圍](https://git-scm.com/docs/gitrevisions)和[提交限制](https://git-scm.com/docs/git-log/#_commit_limiting)。
### 我想找到引用特定提交的標籤
```sh
$ git tag --contains [提交]
```
## 子模組
### 複製所有子模組 ### 複製所有子模組
@ -1478,11 +1557,44 @@ $ git clone --recursive git://github.com/foo/bar.git
$ git submodule update --init --recursive $ git submodule update --init --recursive
``` ```
### 移除子模組
創建子模組很直覺,但刪除不是,你需要:
```sh
$ git submodule deinit [子模組名稱]
$ git rm [子模組名稱]
$ git rm --cached [子模組名稱]
$ rm -rf .git/modules/[子模組名稱]
```
## 雜項
### 從另一個分支拷貝檔案
```sh
$ git checkout [分支] -- [檔案名稱]
```
### 恢復刪除的檔案
先找到該檔案最後存在的提交:
```sh
$ git rev-list -n 1 HEAD -- [檔案名稱]
```
然後簽出該檔案:
```sh
$ git checkout [刪除檔案的提交]^ -- [檔案名稱]
```
### 刪除標籤 ### 刪除標籤
```sh ```sh
$ git tag -d <tag_name> $ git tag -d [標籤名稱]
$ git push <remote> :refs/tags/<tag_name> $ git push [遠端] :refs/tags/[標籤名稱]
``` ```
### 恢復已刪除標籤 ### 恢復已刪除標籤
@ -1493,37 +1605,146 @@ $ git push <remote> :refs/tags/<tag_name>
$ git fsck --unreachable | grep tag $ git fsck --unreachable | grep tag
``` ```
記下這個標籤的雜湊值,然後用 Git 的 [`update-ref`](http://git-scm.com/docs/git-update-ref) 記下這個標籤的雜湊值,然後用 [`git update-ref`](http://git-scm.com/docs/git-update-ref)
```sh ```sh
$ git update-ref refs/tags/<tag_name> <hash> $ git update-ref refs/tags/[標籤名稱] [雜湊值]
``` ```
### 已刪除修補檔 ### 已刪除修補檔
如果有人在 GitHub 上向你提出了拉取請求,但他接著刪除了他的分叉,你無法複製他的提交或使用 `git am`。在這種情況下,最好手動的查看他們的提交,把它們拷貝到一個新的本機分支,然後提交。 如果有人在 GitHub 上向你提出了拉取請求,但他接著刪除了他的分叉,因為 [`.diff` 和 `.patch` URL](https://github.com/blog/967-github-secrets) 失效,你無法複製他的提交或使用 `git am`。但你可以透過 [GitHub 的特殊引用](https://gist.github.com/piscisaureus/3342247)簽出拉取請求本身。例如將拉取請求 #1 的內容抓取到名為 `pr_1` 的新分支:
最後,再修改作者,參見[〈變更作者〉](#commit-wrong-author)。然後,套用更動,再發起一個新的拉取請求。 ```sh
$ git fetch [遠端] refs/pull/1/head:pr_1
From github.com:foo/bar
* [new ref] refs/pull/1/head -> pr_1
```
### 將版本庫導出為 Zip 檔
```sh
$ git archive --format zip --output [zip 的完整檔案路徑] main
```
### 推送有相同名稱的分支與標籤
如果遠端有與分支同名的標籤,若試圖以標準的 `git push [遠端] [分支]` 命令推送該分支時會得到以下錯誤:
```sh
$ git push [遠端] [分支]
error: dst refspec same matches more than one.
error: failed to push some refs to '<git server>'
```
指明要推送 `HEAD` 引用來修正這個問題:
```sh
$ git push [遠端] refs/heads/[分支名稱]
```
相對地,推送標籤使用:
```sh
$ git push [遠端] refs/tags/[標籤名稱]
```
## 追蹤檔案 ## 追蹤檔案
### 我只想改變一個檔案名的大小寫,而不修改內容 ### 我只想改變一個檔案名的大小寫,而不修改內容
```sh ```sh
(main)$ git mv --force myfile MyFile (main)$ git mv --force [原名稱] [新名稱]
``` ```
### 我想從 Git 刪除一個檔案,但保留該檔案 ### 我想在拉取時覆蓋本機檔案
```sh ```sh
(main)$ git rm --cached log.txt (main)$ git fetch --all
(main)$ git reset --hard origin/main
``` ```
### 我想將檔案從 Git 移除,但保留檔案
```sh
(main)$ git rm --cached [檔案名稱]
```
### 我想將特定檔案還原至某個修訂版
```sh
$ git checkout [提交] -- [檔案名稱]
```
還原多個檔案:
```sh
$ git checkout [提交] -- [檔案名稱1] [檔案名稱2]
```
### 我想列出提交或分支之間特定檔案的差異
```sh
$ git diff [提交1]:[檔案名稱] [提交2]:[檔案名稱]
# 或
$ git diff [提交1] [提交2] -- [檔案名稱]
```
當然,也可以用分支名稱來表示分支頂端的提交。
### 我想 Git 忽略特定檔案的更動
這可以用於不應該提交的組態模板或其他需在本機加入憑證的檔案。
```sh
$ git update-index --assume-unchanged [要忽略的檔案]
```
注意,這*並不會*將檔案從版本控制移除——只是在本機上忽略。要取消這個設定,以下命令清除此旗標:
```sh
$ git update-index --no-assume-unchanged [要取消忽略的檔案]
```
## 用 Git 除錯
[`git bisect`](https://git-scm.com/docs/git-bisect) 命令透過二分搜尋找到哪個提交引入了漏洞。
假設你在 `main` 分支上,想找到哪個提交導致程式出錯。你開始二分搜尋:
```sh
$ git bisect start
```
接著你應該指定哪個提交已經包含了這個漏洞,哪個沒有。例如,你目前所在的修訂版是壞的,而 `v1.1.1` 是好的:
```sh
$ git bisect bad
$ git bisect good v1.1.1
```
接著 Git 會簽出你提供的範圍中間的提交,並詢問該提交是好是壞。你應該會看到類似這樣的訊息:
```sh
Bisecting: 5 revision left to test after this (roughly 5 step)
[c44abbbee29cb93d8499283101fe7c8d9d97f0fe] Commit message
(c44abbb)$
```
然後你可以檢查這個提交是好是壞。然後用以下命令告訴 Git
```sh
$ git bisect good # 如果是好的。
$ git bisect bad # 如果是壞的。
```
Git 會從範圍中選擇另一個提交,這個過程將重複直到沒有剩下的修訂版需要檢查,而命令最後會印出**第一個**壞提交。
## 組態 ## 組態
### 我想為 Git 命令設定別名 ### 我想為 Git 命令設定別名
在 OS X 和 Linux 下Git 組態檔案儲存在 `~/.gitconfig`。可以在 `[alias]` 部分設定一些快捷別名(以及容易拼錯的),如: 在 OS X 和 Linux 下Git 組態檔案位於 `~/.gitconfig`。可以在 `[alias]` 部分設定一些快捷別名(以及容易拼錯的),如:
```vim ```vim
[alias] [alias]
@ -1548,18 +1769,84 @@ $ git update-ref refs/tags/<tag_name> <hash>
zap = fetch -p zap = fetch -p
``` ```
### 我想快取一個版本庫的使用者名稱和密碼 ### 我想將空目錄加入到版本庫
假設有一個版本庫需要授權,這時你可以快取使用者名稱和密碼,而不用每次推送和拉取時都輸入一次 你無法這麼做Git 不支援,但有一個技巧——你可以在該目錄創建包含以下內容的 `.gitignore` 檔案
```
# 忽略這個目錄中所有檔案。
.
# 除了這個檔案自身。
!.gitignore
```
另一個慣例是在該目錄中創建一個名為 `.gitkeep` 的空檔案:
```sh ```sh
$ mkdir 空目錄
$ touch 空目錄/.gitkeep
```
你也可以改稱其為 `.keep`,將第二個命令改為 `touch 空目錄/.keep` 即可。
### 我想快取一個版本庫的使用者名稱和密碼
假設有一個版本庫需要身分認證,這時你可以快取使用者名稱和密碼,而不用每次推送和拉取時都輸入一次。憑證協助程式可以做到這點:
```sh
# 設定 Git 使用憑證記憶快取。
$ git config --global credential.helper cache $ git config --global credential.helper cache
# Set Git to use the credential memory cache.
``` ```
```sh ```sh
# 設定快取在 1 小時後過期(以秒為單位)。
$ git config --global credential.helper 'cache --timeout=3600' $ git config --global credential.helper 'cache --timeout=3600'
# Set the cache to timeout after 1 hour (setting is in seconds). ```
顯示可能的憑證協助程式:
```sh
$ git help -a | grep credential
```
作業系統特定的憑證快取協助程式:
```sh
# OS X
$ git config --global credential.helper osxkeychain
```
```sh
# Windows 2.7.3+
$ git config --global credential.helper manager
```
```sh
# Ubuntu 或其他使用 GNOME 的發行版:
$ git config --global credential.helper gnome-keyring
```
其他作業系統和發行版可能有不同的協助程式。
### 我想 Git 忽略權限與檔案模式更動
```sh
$ git config core.fileMode false
```
如果要設定為目前登入的使用者的預設行為:
```sh
$ git config --global core.fileMode false
```
### 我想設定全域使用者資訊
設定跨版本庫的使用者資訊:
```sh
$ git config --global user.name [名字]
$ git config --global user.email [email]
``` ```
## 我不知道我做錯了什麼 ## 我不知道我做錯了什麼
@ -1585,19 +1872,55 @@ $ git reset --hard 0254ea7
摘自[這裡](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)。 摘自[這裡](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)。
## Git 快捷命令
### Git Bash
如果你已經很熟悉以上命令的用法了,你可能會想創建一些快捷方式,讓你可以用很短的命令完成複雜的任務。
```sh
alias sq=squash
function squash() {
git rebase -i HEAD~$1
}
```
將以上命令複製至你的 `.bashrc``.bash_profile`
### Windows 上的 PowerShell
Windows 上的 PowerShell 也可以設定別名與函式。將以下命令加到你位於 `$profile` 變數的設定檔,詳見微軟文件網頁的 [關於設定檔](https://learn.microsoft.com/zh-tw/powershell/module/microsoft.powershell.core/about/about_profiles)。
```powershell
Set-Alias sq Squash-Commit
function Squash-Commit {
git rebase -i HEAD~$1
}
```
# 其他資源 # 其他資源
## 書籍 ## 書籍
* [Pro Git](https://git-scm.com/book/en/v2)——Scott Chacon 的傑出書籍 * [Learn Enough Git to Be Dangerous](https://www.learnenough.com/git-tutorial)——Michael Hartl 所著的從基礎開始的 Git 書籍
* [Pro Git](https://git-scm.com/book/en/v2)——Scott Chacon 與 Ben Straub 合著的傑出書籍
* [Git Internals](https://github.com/pluralsight/git-internals-pdf)——Scott Chacon 的另一本傑出書籍 * [Git Internals](https://github.com/pluralsight/git-internals-pdf)——Scott Chacon 的另一本傑出書籍
* [Nasa Handbook](https://www.nasa.gov/sites/default/files/atoms/files/nasa_systems_engineering_handbook.pdf)
## 教學 ## 教學
* [Learn Git branching](https://learngitbranching.js.org/)——一個基於網頁的互動式分支、合併、重定基底教學 * [19 Git Tips For Everyday Use](https://www.alexkras.com/19-git-tips-for-everyday-use)——實用的 Git 一行命令列表
* [Atlassian's Git tutorial](https://www.atlassian.com/git/tutorials)——從初學到熟練,正確掌握 Git 的教學
* [Learn Git branching](https://learngitbranching.js.org/)——分支、合併、重定基底的互動式網頁教學
* [Getting solid at Git rebase vs. merge](https://medium.com/@porteneuve/getting-solid-at-git-rebase-vs-merge-4fa1a48c53aa) * [Getting solid at Git rebase vs. merge](https://medium.com/@porteneuve/getting-solid-at-git-rebase-vs-merge-4fa1a48c53aa)
* [git-workflow](https://github.com/asmeurer/git-workflow)——[Aaron Meurer](https://github.com/asmeurer) 的怎麼使用 Git 開源貢獻 * [Git Commands and Best Practices Cheat Sheet](https://zeroturnaround.com/rebellabs/git-commands-and-best-practices-cheat-sheet)——一篇部落格中的 Git 小抄與更多解釋
* [GitHub as a workflow](http://hugogiraudel.com/2015/08/13/github-as-a-workflow/)——GitHub 作為工作流程的趣事,特別是空拉取請求 * [Git from the inside out](https://codewords.recurse.com/issues/two/git-from-the-inside-out)——深度探討 Git 內部的教學
* [git-workflow](https://github.com/asmeurer/git-workflow) - [Aaron Meurer](https://github.com/asmeurer)——如何用 Git 貢獻開源版本庫
* [GitHub as a workflow](https://hugogiraudel.com/2015/08/13/github-as-a-workflow/)——將 GitHub 用作工作流程的有趣做法,尤其是空 PR
* [Githug](https://github.com/Gazler/githug)——學習常見 Git 工作流程的遊戲
* [learnGitBranching](https://github.com/pcottle/learnGitBranching)——用於挑戰與教育的互動式 Git 可視化!
## 腳本和工具 ## 腳本和工具
@ -1606,7 +1929,7 @@ $ git reset --hard 0254ea7
* [git-extras](https://github.com/tj/git-extras)——Git 工具集版本庫概要、repl、歷史記錄、提交百分比和更多 * [git-extras](https://github.com/tj/git-extras)——Git 工具集版本庫概要、repl、歷史記錄、提交百分比和更多
* [git-fire](https://github.com/qw3rtman/git-fire)——git-fire 是一個 Git 插件,用於在緊急情況下幫助加入目前所有檔案、提交、推送到一個新分支(防止合併衝突)。 * [git-fire](https://github.com/qw3rtman/git-fire)——git-fire 是一個 Git 插件,用於在緊急情況下幫助加入目前所有檔案、提交、推送到一個新分支(防止合併衝突)。
* [git-tips](https://github.com/git-tips/tips)——Git 小撇步 * [git-tips](https://github.com/git-tips/tips)——Git 小撇步
* [git-town](https://github.com/Originate/git-town)——通用、高級 Git 工作流程支援! http://www.git-town.com * [git-town](https://github.com/Originate/git-town)——通用、高級 Git 工作流程支援!<http://www.git-town.com>
## GUI 客戶端 ## GUI 客戶端
@ -1614,5 +1937,12 @@ $ git reset --hard 0254ea7
* [git-cola](https://git-cola.github.io/)——又一個 Git 客戶端,適用於 Windows、OS X * [git-cola](https://git-cola.github.io/)——又一個 Git 客戶端,適用於 Windows、OS X
* [GitUp](https://github.com/git-up/GitUp)——一個新的 Git 客戶端,在解決 Git 的複雜問題上有自己的特點 * [GitUp](https://github.com/git-up/GitUp)——一個新的 Git 客戶端,在解決 Git 的複雜問題上有自己的特點
* [gitx-dev](https://rowanj.github.io/gitx/)——又一個圖形化的 Git 客戶端,適用於 OS X * [gitx-dev](https://rowanj.github.io/gitx/)——又一個圖形化的 Git 客戶端,適用於 OS X
* [Source Tree](https://www.sourcetreeapp.com/)——簡單而強大的免費 Git GUI 客戶端,適用於 Windows、OS X * [Sourcetree](https://www.sourcetreeapp.com/)——簡單而強大的免費 Git GUI 客戶端,適用於 Windows、OS X
* [Tower](http://www.git-tower.com/)——圖形化 Git 客戶端,適用於 OS X付費 * [Tower](http://www.git-tower.com/)——圖形化 Git 客戶端,適用於 OS X付費
* [tig](https://jonas.github.io/tig/)——Git 的終端文本模式介面
* [Magit](https://magit.vc/)——Emacs 的 Git 介面
* [GitExtensions](https://github.com/gitextensions/gitextensions)——殼層插件、Visual Studio 2010-2015 插件、獨立的 Git 版本庫工具
* [Fork](https://git-fork.com/)——快速且友善的 Git 客戶端,適用於 Macbeta
* [gmaster](https://gmaster.io/)——包含三路合併、分析重構、語意化差異、合併等的 Git 客戶端,適用於 Windowsbeta
* [gitk](https://git-scm.com/docs/gitk)——可以簡單查看版本庫狀態的 Git 客戶端,適用於 Linux
* [SublimeMerge](https://www.sublimemerge.com/)——極速、可擴展的客戶端,有三路合併、強大的搜尋、語法高亮功能,活躍開發中