Replace master with main (issue/#308)

This commit is contained in:
Shota Imaki 2020-11-30 14:13:02 +09:00
parent 82f0b3994d
commit 97309a164c
8 changed files with 703 additions and 703 deletions

208
README.md
View File

@ -70,7 +70,7 @@ All commands should work for at least git version 2.13.0. See the [git website](
- [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 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 committed to master instead of a new branch](#i-committed-to-master-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 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 want to delete local branches that were deleted upstream](#i-want-to-delete-local-branches-that-were-deleted-upstream)
@ -240,15 +240,15 @@ After all of this, do not forget to respond to any code review feedback.
#### Suggesting code via patches
Another approach to suggesting code changes that doesn't rely on third party sites such as Github is to use `git format-patch`.
Another approach to suggesting code changes that doesn't rely on third party sites such as Github is to use `git format-patch`.
`format-patch` creates a .patch file for one or more commits. This file is essentially a list of changes that looks similar to the commit diffs you can view on Github.
`format-patch` creates a .patch file for one or more commits. This file is essentially a list of changes that looks similar to the commit diffs you can view on Github.
A patch can be viewed and even edited by the recipient and applied using `git am`.
For example, to create a patch based on the previous commit you would run `git format-patch HEAD^` which would create a .patch file called something like 0001-My-Commit-Message.patch.
To apply this patch file to your repository you would run `gim am ./0001-My-Commit-Message.patch`.
To apply this patch file to your repository you would run `gim am ./0001-My-Commit-Message.patch`.
Patches can also be sent via email using the `git send-email` command. For information on usage and configuration see: https://git-send-email.io
@ -259,18 +259,18 @@ After a while, the `upstream` repository may have been updated, and these update
You probably have set up a remote that points to the original project. If not, do this now. Generally we use `upstream` as a remote name:
```sh
$ (master) git remote add upstream <link-to-original-repository>
# $ (master) git remote add upstream git@github.com:k88hudson/git-flight-rules.git
$ (main) git remote add upstream <link-to-original-repository>
# $ (main) git remote add upstream git@github.com:k88hudson/git-flight-rules.git
```
Now you can fetch from upstream and get the latest updates.
```sh
$ (master) git fetch upstream
$ (master) git merge upstream/master
$ (main) git fetch upstream
$ (main) git merge upstream/main
# or using a single command
$ (master) git pull upstream master
$ (main) git pull upstream main
```
## Editing Commits
@ -281,7 +281,7 @@ $ (master) git pull upstream master
Let's say that you just blindly committed changes with `git commit -a` and you're not sure what the actual content of the commit you just made was. You can show the latest commit on your current HEAD with:
```sh
(master)$ git show
(main)$ git show
```
Or
@ -410,13 +410,13 @@ If you accidentally do `git reset --hard`, you can normally still get your commi
Note: This is only valid if your work is backed up, i.e., either committed or stashed. `git reset --hard` _will remove_ uncommitted modifications, so use it with caution. (A safer option is `git reset --keep`.)
```sh
(master)$ git reflog
(main)$ git reflog
```
You'll see a list of your past commits, and a commit for the reset. Choose the SHA of the commit you want to return to, and reset again:
```sh
(master)$ git reset --hard SHA1234
(main)$ git reset --hard SHA1234
```
And you should be good to go.
@ -482,17 +482,17 @@ Using bfg-repo-cleaner requires java. Download the bfg jar from the link [here](
To delete a specific file.
```sh
(master)$ git rm path/to/filetoremove
(master)$ git commit -m "Commit removing filetoremove"
(master)$ java -jar ~/Downloads/bfg.jar --delete-files filetoremove
(main)$ git rm path/to/filetoremove
(main)$ git commit -m "Commit removing filetoremove"
(main)$ java -jar ~/Downloads/bfg.jar --delete-files filetoremove
```
Note that in bfg you must use the plain file name even if it is in a subdirectory.
You can also delete a file by pattern, e.g.:
```sh
(master)$ git rm *.jpg
(master)$ git commit -m "Commit removing *.jpg"
(master)$ java -jar ~/Downloads/bfg.jar --delete-files *.jpg
(main)$ git rm *.jpg
(main)$ git commit -m "Commit removing *.jpg"
(main)$ java -jar ~/Downloads/bfg.jar --delete-files *.jpg
```
With bfg, the files that exist on your latest commit will not be affected. For example, if you had several large .tga files in your repo, and then in an earlier commit, you deleted a subset of them, this call does not touch files present in the latest commit
@ -506,7 +506,7 @@ Note, if you renamed a file as part of a commit, e.g. if it started as `LargeFil
In the below, replace `filepattern` may be a specific name or pattern, e.g. `*.jpg`. This will remove files matching the pattern from all history and branches.
```sh
(master)$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch filepattern' --prune-empty --tag-name-filter cat -- --all
(main)$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch filepattern' --prune-empty --tag-name-filter cat -- --all
```
Behind-the-scenes explanation:
@ -520,19 +520,19 @@ Behind-the-scenes explanation:
Once you have removed your desired files, test carefully that you haven't broken anything in your repo - if you have, it is easiest to re-clone your repo to start over.
To finish, optionally use git garbage collection to minimize your local .git folder size, and then force push.
```sh
(master)$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
(master)$ git push origin --force --tags
(main)$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
(main)$ git push origin --force --tags
```
Since you just rewrote the entire git repo history, the `git push` operation may be too large, and return the error `“The remote end hung up unexpectedly”`. If this happens, you can try increasing the git post buffer:
```sh
(master)$ git config http.postBuffer 524288000
(master)$ git push --force
(main)$ git config http.postBuffer 524288000
(main)$ git push --force
```
If this does not work, you will need to manually push the repo history in chunks of commits. In the command below, try increasing `<number>` until the push operation succeeds.
```sh
(master)$ git push -u origin HEAD~<number>:refs/head/master --force
(main)$ git push -u origin HEAD~<number>:refs/head/main --force
```
Once the push operation succeeds the first time, decrease `<number>` gradually until a conventional `git push` succeeds.
@ -681,7 +681,7 @@ If you want to discard all your local staged and unstaged changes, you can do th
```sh
(my-branch)$ git reset --hard
# or
(master)$ git checkout -f
(main)$ git checkout -f
```
This will unstage all files you might have staged with `git add`:
@ -819,7 +819,7 @@ $ git checkout -b <branch> <SHA1_OF_COMMIT>
This is another chance to use `git reflog` to see where your HEAD pointed before the bad pull.
```sh
(master)$ git reflog
(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here
```
@ -850,41 +850,41 @@ Confirm that you haven't pushed your changes to the server.
One way of resetting to match origin (to have the same as what is on the remote) is to do this:
```sh
(master)$ git reset --hard origin/my-branch
(main)$ git reset --hard origin/my-branch
```
<a name="commit-wrong-branch"></a>
### I committed to master instead of a new branch
### I committed to main instead of a new branch
Create the new branch while remaining on master:
Create the new branch while remaining on main:
```sh
(master)$ git branch my-branch
(main)$ git branch my-branch
```
Reset the branch master to the previous commit:
Reset the branch main to the previous commit:
```sh
(master)$ git reset --hard HEAD^
(main)$ git reset --hard HEAD^
```
`HEAD^` is short for `HEAD^1`. This stands for the first parent of `HEAD`, similarly `HEAD^2` stands for the second parent of the commit (merges can have 2 parents).
Note that `HEAD^2` is **not** the same as `HEAD~2` (see [this link](http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde) for more information).
Alternatively, if you don't want to use `HEAD^`, find out what the commit hash you want to set your master branch to (`git log` should do the trick). Then reset to that hash. `git push` will make sure that this change is reflected on your remote.
Alternatively, if you don't want to use `HEAD^`, find out what the commit hash you want to set your main branch to (`git log` should do the trick). Then reset to that hash. `git push` will make sure that this change is reflected on your remote.
For example, if the hash of the commit that your master branch is supposed to be at is `a13b85e`:
For example, if the hash of the commit that your main branch is supposed to be at is `a13b85e`:
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Checkout the new branch to continue working:
```sh
(master)$ git checkout my-branch
(main)$ git checkout my-branch
```
<a name="keep-whole-file"></a>
@ -927,10 +927,10 @@ Note: Spike solutions are made to analyze or solve the problem. These solutions
<a name="cherry-pick"></a>
### I made several commits on a single branch that should be on different branches
Say you are on your master branch. Running `git log`, you see you have made two commits:
Say you are on your main branch. Running `git log`, you see you have made two commits:
```sh
(master)$ git log
(main)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
@ -953,17 +953,17 @@ Date: Tue Jul 21 01:12:48 2014 -0400
Let's take note of our commit hashes for each bug (`e3851e8` for #21, `5ea5173` for #14).
First, let's reset our master branch to the correct commit (`a13b85e`):
First, let's reset our main branch to the correct commit (`a13b85e`):
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Now, we can create a fresh branch for our bug #21:
```sh
(master)$ git checkout -b 21
(main)$ git checkout -b 21
(21)$
```
@ -975,11 +975,11 @@ Now, let's *cherry-pick* the commit for bug #21 on top of our branch. That means
At this point, there is a possibility there might be conflicts. See the [**There were conflicts**](#merge-conflict) section in the [interactive rebasing section above](#interactive-rebase) for how to resolve conflicts.
Now let's create a new branch for bug #14, also based on master
Now let's create a new branch for bug #14, also based on main
```sh
(21)$ git checkout master
(master)$ git checkout -b 14
(21)$ git checkout main
(main)$ git checkout -b 14
(14)$
```
@ -1005,7 +1005,7 @@ where, `upstream` is the remote you want to fetch from.
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:
```sh
(master)$ git checkout -b my-branch
(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
@ -1035,31 +1035,31 @@ Date: Tue Jul 29 13:14:46 2014 -0400
Fixes #6: Force pushing after amending commits
```
Now we're switching back to master and 'accidentally' removing our branch.
Now we're switching back to main and 'accidentally' removing our branch.
```sh
(my-branch)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
(my-branch)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(master)$ echo oh noes, deleted my branch!
(main)$ echo oh noes, deleted my branch!
oh noes, deleted my branch!
```
At this point you should get familiar with 'reflog', an upgraded logger. It stores the history of all the action in the repo.
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to master
(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to main
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from master to my-branch
69204cd HEAD@{2}: checkout: moving from main to my-branch
```
As you can see we have commit hash from our deleted branch. Let's see if we can restore our deleted branch.
```sh
(master)$ git checkout -b my-branch-help
(main)$ git checkout -b my-branch-help
Switched to a new branch 'my-branch-help'
(my-branch-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 foo.txt added
@ -1074,25 +1074,25 @@ Voila! We got our removed file back. `git reflog` is also useful when rebasing g
To delete a remote branch:
```sh
(master)$ git push origin --delete my-branch
(main)$ git push origin --delete my-branch
```
You can also do:
```sh
(master)$ git push origin :my-branch
(main)$ git push origin :my-branch
```
To delete a local branch:
```sh
(master)$ git branch -d my-branch
(main)$ git branch -d my-branch
```
To delete a local branch that *has not* been merged to the current branch or an upstream:
```sh
(master)$ git branch -D my-branch
(main)$ git branch -D my-branch
```
### I want to delete multiple branches
@ -1100,7 +1100,7 @@ To delete a local branch that *has not* been merged to the current branch or an
Say you want to delete all branches that start with `fix/`:
```sh
(master)$ git branch | grep 'fix/' | xargs git branch -d
(main)$ git branch | grep 'fix/' | xargs git branch -d
```
### I want to rename a branch
@ -1108,18 +1108,18 @@ Say you want to delete all branches that start with `fix/`:
To rename the current (local) branch:
```sh
(master)$ git branch -m new-name
(main)$ git branch -m new-name
```
To rename a different (local) branch:
```sh
(master)$ git branch -m old-name new-name
(main)$ git branch -m old-name new-name
```
To delete the `old-name` remote branch and push the `new-name` local branch:
```sh
(master)$ 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>
@ -1128,13 +1128,13 @@ To rename a different (local) branch:
First, fetch all branches from remote:
```sh
(master)$ git fetch --all
(main)$ git fetch --all
```
Say you want to checkout to `daves` from the remote.
```sh
(master)$ git checkout --track origin/daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
```
@ -1187,14 +1187,14 @@ By checking your remote branches, you can see which remote branch your HEAD is t
```sh
$ git branch -r
origin/HEAD -> origin/gh-pages
origin/master
origin/main
```
To change `origin/HEAD` to track `origin/master`, you can run this command:
To change `origin/HEAD` to track `origin/main`, you can run this command:
```sh
$ git remote set-head origin --auto
origin/HEAD set to master
origin/HEAD set to main
```
### I made changes on the wrong branch
@ -1224,10 +1224,10 @@ You may have merged or rebased your current branch with a wrong branch, or you c
Unfortunately, you have to force push, if you want those changes to be reflected on the remote branch. This is because you have changed the history. The remote branch won't accept changes unless you force push. This is one of the main reasons many people use a merge workflow, instead of a rebasing workflow - large teams can get into trouble with developers force pushing. Use this with caution. A safer way to use rebase is not to reflect your changes on the remote branch at all, and instead to do the following:
```sh
(master)$ git checkout my-branch
(my-branch)$ git rebase -i master
(my-branch)$ git checkout master
(master)$ git merge --ff-only my-branch
(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch
```
For more, see [this SO thread](https://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push).
@ -1235,23 +1235,23 @@ For more, see [this SO thread](https://stackoverflow.com/questions/11058312/how-
<a name="interactive-rebase"></a>
### I need to combine commits
Let's suppose you are working in a branch that is/will become a pull-request against `master`. In the simplest case when all you want to do is to combine *all* commits into a single one and you don't care about commit timestamps, you can reset and recommit. Make sure the master branch is up to date and all your changes committed, then:
Let's suppose you are working in a branch that is/will become a pull-request against `main`. In the simplest case when all you want to do is to combine *all* commits into a single one and you don't care about commit timestamps, you can reset and recommit. Make sure the main branch is up to date and all your changes committed, then:
```sh
(my-branch)$ git reset --soft master
(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"
```
If you want more control, and also to preserve timestamps, you need to do something called an interactive rebase:
```sh
(my-branch)$ git rebase -i master
(my-branch)$ git rebase -i main
```
If you aren't working against another branch you'll have to rebase relative to your `HEAD`. If you want to squash the last 2 commits, for example, you'll have to rebase against `HEAD~2`. For the last 3, `HEAD~3`, etc.
```sh
(master)$ git rebase -i HEAD~2
(main)$ git rebase -i HEAD~2
```
After you run the interactive rebase command, you will see something like this in your text editor:
@ -1311,7 +1311,7 @@ Newer, awesomer features
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
# modified: README.md
@ -1322,20 +1322,20 @@ Newer, awesomer features
If everything is successful, you should see something like this:
```sh
(master)$ Successfully rebased and updated refs/heads/master.
(main)$ Successfully rebased and updated refs/heads/main.
```
#### Safe merging strategy
`--no-commit` performs the merge but pretends the merge failed and does not autocommit, giving the user a chance to inspect and further tweak the merge result before committing. `no-ff` maintains evidence that a feature branch once existed, keeping project history consistent.
```sh
(master)$ git merge --no-ff --no-commit my-branch
(main)$ git merge --no-ff --no-commit my-branch
```
#### I need to merge a branch into a single commit
```sh
(master)$ git merge --squash my-branch
(main)$ git merge --squash my-branch
```
<a name="rebase-unpushed-commits"></a>
@ -1344,7 +1344,7 @@ If everything is successful, you should see something like this:
Sometimes you have several work in progress commits that you want to combine before you push them upstream. You don't want to accidentally combine any commits that have already been pushed upstream because someone else may have already made commits that reference them.
```sh
(master)$ git rebase -i @{u}
(main)$ git rebase -i @{u}
```
This will do an interactive rebase that lists only the commits that you haven't already pushed, so it will be safe to reorder/fix/squash anything in the list.
@ -1361,7 +1361,7 @@ This command is available since Git version >= 1.7.4
### I need to update the parent commit of my branch
Say I have a master branch, a feature-1 branch branched from master, and a feature-2 branch branched off of feature-1. If I make a commit to feature-1, then the parent commit of feature-2 is no longer accurate (it should be the head of feature-1, since we branched off of it). We can fix this with `git rebase --onto`.
Say I have a main branch, a feature-1 branch branched from main, and a feature-2 branch branched off of feature-1. If I make a commit to feature-1, then the parent commit of feature-2 is no longer accurate (it should be the head of feature-1, since we branched off of it). We can fix this with `git rebase --onto`.
```sh
(feature-2)$ git rebase --onto feature-1 <the first commit in your feature-2 branch that you don't want to bring along> feature-2
@ -1374,13 +1374,13 @@ This helps in sticky scenarios where you might have a feature built on another f
To check if all commits on a branch are merged into another branch, you should diff between the heads (or any commits) of those branches:
```sh
(master)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
```
This will tell you if any commits are in one but not the other, and will give you a list of any nonshared between the branches. Another option is to do this:
```sh
(master)$ git log master ^feature/120-on-scroll --no-merges
(main)$ git log main ^feature/120-on-scroll --no-merges
```
### Possible issues with interactive rebases
@ -1395,7 +1395,7 @@ noop
That means you are trying to rebase against a branch that is at an identical commit, or is *ahead* of your current branch. You can try:
* making sure your master branch is where it should be
* making sure your main branch is where it should be
* rebase against `HEAD~2` or earlier instead
<a name="merge-conflict"></a>
@ -1430,7 +1430,7 @@ You will need to resolve the differences between the code that was added in your
If you want to keep one branch's version of the code, you can use `--ours` or `--theirs`:
```sh
(master*)$ git checkout --ours README.md
(main*)$ git checkout --ours README.md
```
- When *merging*, use `--ours` to keep changes from the local branch, or `--theirs` to keep changes from the other branch.
@ -1439,7 +1439,7 @@ If you want to keep one branch's version of the code, you can use `--ours` or `-
If the merges are more complicated, you can use a visual diff editor:
```sh
(master*)$ git mergetool -t opendiff
(main*)$ git mergetool -t opendiff
```
After you have resolved all conflicts and tested your code, `git add` the files you have changed, and then continue the rebase with `git rebase --continue`
@ -1689,7 +1689,7 @@ From github.com:foo/bar
### Exporting a repository as a Zip file
```sh
$ git archive --format zip --output /full/path/to/zipfile.zip master
$ git archive --format zip --output /full/path/to/zipfile.zip main
```
### Push a branch and a tag that have the same name
@ -1719,21 +1719,21 @@ $ git push origin refs/tags/<tag-name>
### I want to change a file name's capitalization, without changing the contents of the file
```sh
(master)$ git mv --force myfile MyFile
(main)$ git mv --force myfile MyFile
```
### I want to overwrite local files when doing a git pull
```sh
(master)$ git fetch --all
(master)$ git reset --hard origin/master
(main)$ git fetch --all
(main)$ git reset --hard origin/main
```
<a href="remove-from-git"></a>
### I want to remove a file from Git but keep the file
```sh
(master)$ git rm --cached log.txt
(main)$ git rm --cached log.txt
```
### I want to revert a file to a specific revision
@ -1741,13 +1741,13 @@ $ git push origin refs/tags/<tag-name>
Assuming the hash of the commit you want is c5f567:
```sh
(master)$ git checkout c5f567 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567 -- file1/to/restore file2/to/restore
```
If you want to revert to changes made just 1 commit before c5f567, pass the commit hash as c5f567~1:
```sh
(master)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
```
### I want to list changes of a specific file between commits or branches
@ -1761,7 +1761,7 @@ $ git diff HEAD:path_to_file/file c5f567:path_to_file/file
Same goes for branches:
```sh
$ git diff master:path_to_file/file staging:path_to_file/file
$ git diff main:path_to_file/file staging:path_to_file/file
```
### I want Git to ignore changes to a specific file
@ -1782,7 +1782,7 @@ $ git update-index --no-assume-unchanged file-to-stop-ignoring
The [git-bisect](https://git-scm.com/docs/git-bisect) command uses a binary search to find which commit in your Git history introduced a bug.
Suppose you're on the `master` branch, and you want to find the commit that broke some feature. You start bisect:
Suppose you're on the `main` branch, and you want to find the commit that broke some feature. You start bisect:
```sh
$ git bisect start
@ -1841,7 +1841,7 @@ On OS X and Linux, your git configuration file is stored in ```~/.gitconfig```.
wip = rebase -i @{u}
zap = fetch -p
day = log --reverse --no-merges --branches=* --date=local --since=midnight --author=\"$(git config --get user.name)\"
delete-merged-branches = "!f() { git checkout --quiet master && git branch --merged | grep --invert-match '\\*' | xargs -n 1 git branch --delete; git checkout --quiet @{-1}; }; f"
delete-merged-branches = "!f() { git checkout --quiet main && git branch --merged | grep --invert-match '\\*' | xargs -n 1 git branch --delete; git checkout --quiet @{-1}; }; f"
```
### I want to add an empty directory to my repository
@ -1944,21 +1944,21 @@ So, you're screwed - you `reset` something, or you merged the wrong branch, or y
This is what `git reflog` is for. `reflog` keeps track of any changes to the tip of a branch, even if that tip isn't referenced by a branch or a tag. Basically, every time HEAD changes, a new entry is added to the reflog. This only works for local repositories, sadly, and it only tracks movements (not changes to a file that weren't recorded anywhere, for instance).
```sh
(master)$ git reflog
(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
```
The reflog above shows a checkout from master to the 2.2 branch and back. From there, there's a hard reset to an older commit. The latest activity is represented at the top labeled `HEAD@{0}`.
The reflog above shows a checkout from main to the 2.2 branch and back. From there, there's a hard reset to an older commit. The latest activity is represented at the top labeled `HEAD@{0}`.
If it turns out that you accidentally moved back, the reflog will contain the commit master pointed to (0254ea7) before you accidentally dropped 2 commits.
If it turns out that you accidentally moved back, the reflog will contain the commit main pointed to (0254ea7) before you accidentally dropped 2 commits.
```sh
$ git reset --hard 0254ea7
```
Using `git reset` it is then possible to change master back to the commit it was before. This provides a safety net in case history was accidentally changed.
Using `git reset` it is then possible to change main back to the commit it was before. This provides a safety net in case history was accidentally changed.
(copied and edited from [Source](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)).

View File

@ -55,7 +55,7 @@ En aras de la claridad, todos los ejemplos de este documento usan un indicador d
- [Crear una rama desde una confirmación](#crear-una-rama-desde-una-confirmaci%C3%B3n)
- [Hice pull de / en la rama incorrecta](#hice-pull-de--en-la-rama-incorrecta)
- [Quiero descartar confirmaciones locales para que mi rama sea la misma que la del servidor](#quiero-descartar-confirmaciones-locales-para-que-mi-rama-sea-la-misma-que-la-del-servidor)
- [Hice commit a master en lugar de una nueva rama](#hice-commit-a-master-en-lugar-de-una-nueva-rama)
- [Hice commit a main en lugar de una nueva rama](#hice-commit-a-main-en-lugar-de-una-nueva-rama)
- [Quiero mantener todo el archivo de otro ref-ish](#quiero-mantener-todo-el-archivo-de-otro-ref-ish)
- [Realicé varios commits en una sola rama que debería estar en diferentes ramas](#realic%C3%A9-varios-commits-en-una-sola-rama-que-deber%C3%ADa-estar-en-diferentes-ramas)
- [Quiero eliminar las ramas locales que se eliminaron en sentido ascendente](#quiero-eliminar-las-ramas-locales-que-se-eliminaron-en-sentido-ascendente)
@ -142,7 +142,7 @@ $ git clone [url]
Digamos que simplemente hiciste cambios a ciegas con `git commit -a` y no estás seguro de cuál fue el contenido real de la confirmación que acabas de realizar. Puedes mostrar el último commit en su HEAD actual con:
```sh
(master)$ git show
(main)$ git show
```
o
@ -245,13 +245,13 @@ Si estás *absolutamente* seguro que nadie está trabajando en la misma rama o q
Si accidentalmente hiciste `git reset --hard`, puedes volver a obtener tus commits de vuelta ya que git mantiene un registro de todo durante unos días.
```sh
(master)$ git reflog
(main)$ git reflog
```
Verás una lista de tus antiguos commits, y un commit para el reset. Escoge el SHA del commit al que quieres retornar y has el reset de nuevo:
```sh
(master)$ git reset --hard SHA1234
(main)$ git reset --hard SHA1234
```
Y deberías estar ubicado en ese commit.
@ -361,7 +361,7 @@ Si deseas descartar todos los cambios organizados y no supervisados locale
```sh
(mi-rama) $ git reset --hard
# o
(master) $ git checkout -f
(main) $ git checkout -f
```
Esto borrará todos los archivos que hayas organizado con `git add`:
@ -485,7 +485,7 @@ $ git checkout -b <branch> <SHA1_OF_COMMIT>
Esta es otra oportunidad de usar `git reflog` para ver dónde apuntó el HEAD antes del mal tirón.
```sh
(master) $ git reflog
(main) $ git reflog
ab7555f HEAD @ {0}: pull-wrong-branch: Fast-forward
c5bc55a HEAD @ {1}: checkout: checkout message goes here
```
@ -515,21 +515,21 @@ Confirma que no ha enviado sus cambios al servidor.
Una forma de reiniciar para hacer coincidir el origin (tener lo mismo que lo que está en el control remoto) es hacer esto:
```sh
(master) $ git reset --hard origin / my-branch
(main) $ git reset --hard origin / my-branch
```
### Hice commit a master en lugar de una nueva rama
### Hice commit a main en lugar de una nueva rama
Crea la nueva rama mientras permaneces en master:
Crea la nueva rama mientras permaneces en main:
```sh
(master) $ git branch my-branch
(main) $ git branch my-branch
```
Restablece la rama master al commit anterior:
Restablece la rama main al commit anterior:
```sh
(master) $ git reset --hard HEAD ^
(main) $ git reset --hard HEAD ^
```
`HEAD ^` es la abreviatura de `HEAD ^ 1`. Esto representa el primer padre de `HEAD`, del mismo modo` HEAD ^ 2` representa el segundo padre del commit (las fusiones pueden tener 2 padres).
@ -541,14 +541,14 @@ Alternativamente, si no quieres usar `HEAD ^`, averigüe a qué hash de confirma
Por ejemplo, si el hash del commit en el que se supone que está su rama principal es `a13b85e`:
```sh
(master) $ git reset --hard a13b85e
(main) $ git reset --hard a13b85e
HEAD is now at a13b85e
```
Verifique la nueva rama para continuar trabajando:
```sh
(master) $ git checkout my-branch
(main) $ git checkout my-branch
```
### Quiero mantener todo el archivo de otro ref-ish
@ -592,7 +592,7 @@ Nota: Las soluciones de Spike están hechas para analizar o resolver el problema
Digamos que estás en tu rama principal. Al ejecutar `git log`, verás que ha realizado dos commits:
```sh
(master) $ git log
(main) $ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
@ -618,14 +618,14 @@ Toma nota de nuestros hashes de confirmación para cada error (`e3851e8` para #
Primero, restablece la rama principal al commit correcto (`a13b85e`):
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Ahora, puedes crear una nueva rama para la rama bug # 21:
```sh
(master) $ git checkout -b 21
(main) $ git checkout -b 21
(21) $
```
@ -637,11 +637,11 @@ Ahora, * selecciona con precisión * el commit para el error # 21 en la parte su
En este punto, existe la posibilidad de que haya conflictos. Consulta la sección ** Hubo conflictos ** (# conflicto de fusión) en la [sección interactiva de rebase más arriba] (# interactive-rebase) para saber cómo resolver conflictos.
Ahora creamos una nueva rama para el error # 14, también basado en el master
Ahora creamos una nueva rama para el error # 14, también basado en el main
```sh
(21) $ git checkout master
(master) $ git checkout -b 14
(21) $ git checkout main
(main) $ git checkout -b 14
(14) $
```
@ -665,7 +665,7 @@ donde, 'ascendente' es el control remoto desde el que desea recuperar.
Si empujas regularmente hacia el control remoto, deberías estar seguro la mayor parte del tiempo. Pero aún así a veces puede terminar borrando sus ramaes. Digamos que creamos una rama y creamos un nuevo archivo:
```sh
(master)$ git checkout -b my-branch
(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
@ -695,31 +695,31 @@ Date: Tue Jul 29 13:14:46 2014 -0400
Fixes #6: Force pushing after amending commits
```
Ahora estamos volviendo a "master" y "accidentalmente" eliminando nuestra rama.
Ahora estamos volviendo a "main" y "accidentalmente" eliminando nuestra rama.
```sh
(my-branch)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
(my-branch)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(master)$ echo oh noes, deleted my branch!
(main)$ echo oh noes, deleted my branch!
oh noes, deleted my branch!
```
En este punto, debe familiarizarse con 'reflog', un registrador actualizado. Almacena el historial de todas las acciones en el repositorio.
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to master
(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to main
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from master to my-branch
69204cd HEAD@{2}: checkout: moving from main to my-branch
```
Como puede ver, hemos confirmado el hash de nuestra rama eliminada. Veamos si podemos restaurar nuestra rama eliminada.
```sh
(master)$ git checkout -b my-branch-help
(main)$ git checkout -b my-branch-help
Switched to a new branch 'my-branch-help'
(my-branch-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 foo.txt added
@ -734,25 +734,25 @@ Voila! Recuperamos nuestro archivo eliminado. `git reflog` también es útil cua
Para eliminar una rama remota:
```sh
(master) $ git push origin --delete my-branch
(main) $ git push origin --delete my-branch
```
También puedes hacer:
```sh
(master) $ git push origin: my-branch
(main) $ git push origin: my-branch
```
Para eliminar una rama local:
```sh
(master) $ git branch -d my-branch
(main) $ git branch -d my-branch
```
Para eliminar una rama local que * no * se ha fusionado con la rama actual o una cadena ascendente:
```sh
(master) $ git branch -D my-branch
(main) $ git branch -D my-branch
```
### Quiero eliminar varias ramas
@ -760,7 +760,7 @@ Para eliminar una rama local que * no * se ha fusionado con la rama actual o una
Supongamos que quiere eliminar todas las ramas que comienzan con `fix /`:
```sh
(master) $ git rama | grep 'fix /' | xargs git branch -d
(main) $ git rama | grep 'fix /' | xargs git branch -d
```
### Quiero cambiar el nombre de una rama
@ -768,13 +768,13 @@ Supongamos que quiere eliminar todas las ramas que comienzan con `fix /`:
Para cambiar el nombre de la rama actual (local):
```sh
(master) $ git branch -m new-name
(main) $ git branch -m new-name
```
Para cambiar el nombre de una rama diferente (local):
```sh
(master) $ git branch -m old-name new-name
(main) $ git branch -m old-name new-name
```
### Quiero hacer checkout en una rama remota en la que alguien más está trabajando
@ -782,13 +782,13 @@ Para cambiar el nombre de una rama diferente (local):
Primero, busca todas las ramas desde el control remoto:
```sh
(master)$ git fetch --all
(main)$ git fetch --all
```
Digamos que quieres hacer checkout a `daves` desde el repositorio remoto.
```sh
(master)$ git checkout --track origin/daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
```
@ -840,14 +840,14 @@ Al verificar tus ramas remotas, puedes ver en qué rama remota está rastreando
```sh
$ git branch -r
origin/HEAD -> origin/gh-pages
origin/master
origin/main
```
Cambiar `origin / HEAD` para rastrear` origin / master`, puedes ejecutar este comando:
Cambiar `origin / HEAD` para rastrear` origin / main`, puedes ejecutar este comando:
```sh
$ git remote set-head origin --auto
origin/HEAD set to master
origin/HEAD set to main
```
## Rebasing y Merging
@ -867,20 +867,20 @@ Desafortunadamente, debes forzar el push, si deseas que esos cambios se reflejen
```sh
(master)$ git checkout my-branch
(my-branch)$ git rebase -i master
(my-branch)$ git checkout master
(master)$ git merge --ff-only my-branch
(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch
```
Para obtener más información, consulte [este thread SO] (https://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push).
### Necesito combinar commits
Supongamos que estás trabajando en una rama que es / se convertirá en un pull request contra master. En el caso más simple, cuando todo lo que quiere hacer es combinar todos los commits en uno solo y no le importa cometer timestamps, puedes restablecer y volver a hacer el commit. Asegúrate de que la rama principal esté actualizada y de que se hayan confirmado todos los cambios, luego:
Supongamos que estás trabajando en una rama que es / se convertirá en un pull request contra main. En el caso más simple, cuando todo lo que quiere hacer es combinar todos los commits en uno solo y no le importa cometer timestamps, puedes restablecer y volver a hacer el commit. Asegúrate de que la rama principal esté actualizada y de que se hayan confirmado todos los cambios, luego:
```sh
(my-branch)$ git reset --soft master
(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"
```
@ -888,13 +888,13 @@ Si deseas más control y también conservar las marcas de tiempo, debe hacer alg
```sh
(my-branch)$ git rebase -i master
(my-branch)$ git rebase -i main
```
Si no estás trabajando contra otra rama tendrás que volver a establecer una base relativa a tu `HEAD`. Si quieres aplastar las últimas 2 confirmaciones, por ejemplo, tendrás que volver a calcular contra `HEAD ~ 2`. Para los últimos 3, `HEAD ~ 3`, etc.
```sh
(master)$ git rebase -i HEAD~2
(main)$ git rebase -i HEAD~2
```
Después de ejecutar el comando de rebase interactivo, verás algo como esto en tu editor de texto:
@ -956,7 +956,7 @@ Newer, awesomer features
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
# modified: README.md
@ -967,20 +967,20 @@ Newer, awesomer features
Si todo tiene éxito, deberías ver algo como esto:
```sh
(master)$ Successfully rebased and updated refs/heads/master.
(main)$ Successfully rebased and updated refs/heads/main.
```
#### Estrategia de merge segura
`--no-commit` realiza el merge, pero simula que la combinación falló y no se confirma automáticamente, lo que le da al usuario la oportunidad de inspeccionar y modificar aún más el resultado de la combinación antes de realizar la tarea. `no-ff` mantiene la evidencia de que alguna vez existió una rama de características, manteniendo la historia del proyecto consistente.
```sh
(master)$ git merge --no-ff --no-commit my-branch
(main)$ git merge --no-ff --no-commit my-branch
```
#### Necesito fusionar una rama en un solo commit
```sh
(master)$ git merge --squash my-branch
(main)$ git merge --squash my-branch
```
#### Quiero combinar solo los commits sin haber hecho push
@ -988,7 +988,7 @@ Si todo tiene éxito, deberías ver algo como esto:
A veces tiene varios commits en progreso que deseas combinar antes de hacer push. No deseas combinar accidentalmente ningún commit que ya haya sido pusheado porque otra persona ya haya realizado commits que les hagan referencia.
```sh
(master)$ git rebase -i @{u}
(main)$ git rebase -i @{u}
```
Esto hará una base de datos interactiva que enumera solo los commits que aún no has enviado, por lo que será seguro reordenar / arreglar / aplastar cualquier elemento de la lista.
@ -1008,13 +1008,13 @@ Este comando está disponible desde la versión de Git> = 1.7.4
Para comprobar si todos los commits de una rama se fusionan en otra, debe distinguir las cabeceras (o los commits) de esas ramas:
```sh
(master)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
```
Esto te dirá si hay commits en una pero no en la otra, y te dará una lista de las no compartidas entre las ramas. Otra opción es hacer esto:
```sh
(master)$ git log master ^feature/120-on-scroll --no-merges
(main)$ git log main ^feature/120-on-scroll --no-merges
```
### Posibles problemas con rebase interactivos
@ -1062,7 +1062,7 @@ Tendrás que resolver las diferencias entre el código que se agregó en tu nuev
Si deseas conservar la versión del código de una rama, puedes usar `--us` o` --theirs`:
```sh
(master*)$ git checkout --ours README.md
(main*)$ git checkout --ours README.md
```
- Cuando haces *merge*, usa `--ours` para mantener los cambios de la rama local, o` --theirs` para mantener los cambios de la otra rama.
@ -1071,7 +1071,7 @@ Si deseas conservar la versión del código de una rama, puedes usar `--us` o` -
Si las fusiones son más complicadas, puede usar un editor visual diff:
```sh
(master*)$ git mergetool -t opendiff
(main*)$ git mergetool -t opendiff
```
Después de haber resuelto todos los conflictos y probado el código, `git add` los archivos que has cambiado, y luego continúa el rebase con` git rebase --continue`
@ -1275,7 +1275,7 @@ From github.com:foo/bar
### Exportar un repositorio como un archivo Zip
```sh
$ git archive --format zip --output /full/path/to/zipfile.zip master
$ git archive --format zip --output /full/path/to/zipfile.zip main
```
## Seguimiento de archivos
@ -1283,20 +1283,20 @@ $ git archive --format zip --output /full/path/to/zipfile.zip master
### Quiero cambiar el uso de mayúsculas de un nombre de archivo, sin cambiar el contenido del archivo
```sh
(master)$ git mv --force myfile MyFile
(main)$ git mv --force myfile MyFile
```
### Quiero sobrescribir los archivos locales cuando hago un git pull
```sh
(master)$ git fetch --all
(master)$ git reset --hard origin/master
(main)$ git fetch --all
(main)$ git reset --hard origin/main
```
### Quiero eliminar un archivo de Git pero mantener el archivo
```sh
(master)$ git rm --cached log.txt
(main)$ git rm --cached log.txt
```
### Quiero revertir un archivo a una revisión específica
@ -1304,13 +1304,13 @@ $ git archive --format zip --output /full/path/to/zipfile.zip master
Suponiendo que el hash del commit que deseas es c5f567:
```sh
(master)$ git checkout c5f567 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567 -- file1/to/restore file2/to/restore
```
Si desea volver a los cambios realizados solo 1 commit antes de c5f567, pase el hash de confirmación como c5f567 ~ 1:
```sh
(master)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
```
## Configuración
@ -1395,21 +1395,21 @@ Entonces, estás jodido, "reiniciaste" algo, o fusionaste la rama incorrecta, o
Para esto está hecho `git reflog`. `reflog` realiza un seguimiento de los cambios en la punta de una rama, incluso si esa sugerencia no está referenciada por una rama o una etiqueta. Básicamente, cada vez que HEAD cambia, se agrega una nueva entrada al reflog. Esto solo funciona para los repositorios locales, lamentablemente, y solo rastrea los movimientos (no los cambios a un archivo que no fueron grabados en ninguna parte, por ejemplo).
```sh
(master)$ git reflog
(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
```
El reflog anterior muestra una salida desde master a la rama 2.2 y viceversa. A partir de ahí, hay un restablecimiento completo de un commit más antiguo. La última actividad se representa en la parte superior con la etiqueta 'HEAD @ {0} `.
El reflog anterior muestra una salida desde main a la rama 2.2 y viceversa. A partir de ahí, hay un restablecimiento completo de un commit más antiguo. La última actividad se representa en la parte superior con la etiqueta 'HEAD @ {0} `.
Si resulta que retrocedió accidentalmente, el reflog contendrá el master de un commit apuntado a (0254ea7) antes de que accidentalmente soltara 2 commits.
Si resulta que retrocedió accidentalmente, el reflog contendrá el main de un commit apuntado a (0254ea7) antes de que accidentalmente soltara 2 commits.
```sh
$ git reset --hard 0254ea7
```
Usando `git reset` es posible cambiar el master al commit que era antes. Esto proporciona una red de seguridad en caso de que la historia se haya cambiado accidentalmente.
Usando `git reset` es posible cambiar el main al commit que era antes. Esto proporciona una red de seguridad en caso de que la historia se haya cambiado accidentalmente.
(copiado y editado desde [Fuente] (https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)).

View File

@ -57,7 +57,7 @@ Toutes les commandes devraient fonctionner pour les versions de Git au moins sup
- [Créer une branche à partir d'un commit](#cr%C3%A9er-une-branche-%C3%A0-partir-dun-commit)
- [J'ai pull depuis/vers la mauvaise branche](#jai-pull-depuisvers-la-mauvaise-branche)
- [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-%C3%A0-celle-sur-le-serveur)
- [J'ai commité sur master au lieu d'une nouvelle branche](#jai-commit%C3%A9-sur-master-au-lieu-dune-nouvelle-branche)
- [J'ai commité sur main au lieu d'une nouvelle branche](#jai-commit%C3%A9-sur-main-au-lieu-dune-nouvelle-branche)
- [Je veux séparer tout un fichier d'un autre ref-ish](#je-veux-s%C3%A9parer-tout-un-fichier-dun-autre-ref-ish)
- [J'ai fait plusieurs commits sur une même branche qui auraient dû être sur plusieurs branches](#jai-fait-plusieurs-commits-sur-une-m%C3%AAme-branche-qui-auraient-d%C3%BB-%C3%AAtre-sur-plusieurs-branches)
- [Je veux supprimer mes branches locales qui ont été supprimée sur le dépôt distant](#je-veux-supprimer-mes-branches-locales-qui-ont-%C3%A9t%C3%A9-supprim%C3%A9e-sur-le-d%C3%A9p%C3%B4t-distant)
@ -160,7 +160,7 @@ $ git clone [url] nom-du-nouveau-dossier
Imaginons que vous venez tout juste d'enregistrer des changements à l'aveugle avec {code0}git commit -a{/code0} et que vous n'êtes pas sûr·e du contenu réel du commit que vous venez d'effectuer. Vous pouvez visualiser le dernier commit sur votre HEAD actuel avec :
```sh
(master)$ git show
(main)$ git show
```
Ou :
@ -288,13 +288,13 @@ Si vous avez accidentellement fait un `git reset --hard`, vous pouvez normalemen
À noter : Cela n'est valide que si votre travail est sauvegardé, c'est à dire dans un commit ou un remisage. `git reset --hard` *supprimera* les modifications non commitées, donc utilisez cela avec précaution (une option plus sûre est `git reset --keep`).
```sh
(master)$ git reflog
(main)$ git reflog
```
Vous verrez une liste de vos précédents commits, et un commit pour la réinitialisation. Choisissez le SHA du commit vers lequel vous souhaitez retourner, et réinitialisez à nouveau :
```sh
(master)$ git reset --hard SHA1234
(main)$ git reset --hard SHA1234
```
Et cela devrait faire l'affaire.
@ -420,7 +420,7 @@ Si vous voulez vous débarrasser de toutes vos modifications locales indexées e
```sh
(ma-branche)$ git reset --hard
# ou
(master)$ git checkout -f
(main)$ git checkout -f
```
Cette commande désindexera tous les fichiers que vous avez pu indexer avec `git add` :
@ -556,7 +556,7 @@ $ git checkout -b <branche> <SHA1_DU_COMMIT>
C'est une autre occasion d'utiliser `git reflog` afin de voir où votre HEAD pointait avant le mauvais `pull` :
```sh
(master)$ git reflog
(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here
```
@ -588,41 +588,41 @@ Assurez-vous que vous n'avez pas poussé vos modifications sur le serveur.
Une des façons de faire pour réinitialiser votre branche afin qu'elle corresponde à origin (afin d'avoir la même chose que le dépôt distant) est de lancer ceci :
```sh
(master)$ git reset --hard origin/ma-branche
(main)$ git reset --hard origin/ma-branche
```
<a name="commit-wrong-branch"></a>
### J'ai commité sur master au lieu d'une nouvelle branche
### J'ai commité sur main au lieu d'une nouvelle branche
Créez la nouvelle branche tout en restant sur master :
Créez la nouvelle branche tout en restant sur main :
```sh
(master)$ git branch ma-branche
(main)$ git branch ma-branche
```
Réinitialisez la branche master vers le commit précédent :
Réinitialisez la branche main vers le commit précédent :
```sh
(master)$ git reset --hard HEAD^
(main)$ git reset --hard HEAD^
```
`HEAD^` est un raccourci pour `HEAD^1`. Cela indique le premier parent de `HEAD`, de la même façon que `HEAD^2` indique le second parent du commit (des fusions peuvent avoir deux parents).
Notez que `HEAD^2` ne signifie **pas** la même chose que `HEAD~2` (visitez [ce lien](http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde) pour plus d'informations).
Alternativement, si vous ne souhaitez pas utiliser `HEAD^`, retrouvez le hash du commit vers lequel vous souhaitez remettre votre branche master (`git log` devrait faire l'affaire). Puis réinitialisez vers ce hash. `git push` s'assurera que la modification est reflétée sur le serveur distant.
Alternativement, si vous ne souhaitez pas utiliser `HEAD^`, retrouvez le hash du commit vers lequel vous souhaitez remettre votre branche main (`git log` devrait faire l'affaire). Puis réinitialisez vers ce hash. `git push` s'assurera que la modification est reflétée sur le serveur distant.
Par exemple, si le hash du commit sur lequel votre branche master est supposée être est `a13b85e` :
Par exemple, si le hash du commit sur lequel votre branche main est supposée être est `a13b85e` :
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Déplacez-vous vers la nouvelle branche pour continuer de travailler :
```sh
(master)$ git checkout ma-branche
(main)$ git checkout ma-branche
```
<a name="keep-whole-file"></a>
@ -665,10 +665,10 @@ Note: Les pics de solutions servent à analyser ou résoudre un problème. Ces s
<a name="cherry-pick"></a>
### J'ai fait plusieurs commits sur une même branche qui auraient dû être sur plusieurs branches
Admettons que vous êtes sur votre branche master. En lançant `git log`, vous remarquez que vous avez fait deux commits :
Admettons que vous êtes sur votre branche main. En lançant `git log`, vous remarquez que vous avez fait deux commits :
```sh
(master)$ git log
(main)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
@ -691,17 +691,17 @@ Date: Tue Jul 21 01:12:48 2014 -0400
Notons dans un coin les hashes des commits pour chaque bug (`e3851e8` pour le #21, `5ea5173` pour le #14).
Pour commencer, réinitialisons notre branche master sur le bon commit (`a13b85e`) :
Pour commencer, réinitialisons notre branche main sur le bon commit (`a13b85e`) :
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Maintenant, nous pouvons créer une nouvelle branche pour le bug #21 :
```sh
(master)$ git checkout -b 21
(main)$ git checkout -b 21
(21)$
```
@ -713,11 +713,11 @@ Maintenant, faisons un `cherry-pick` du commit pour le bug #21 par-dessus notre
Lors de cette étape, il est possible qu'il y ait des conflits. Regardez la section [**Il y a eu des conflits**](#merge-conflict) dans la section [faire un rebase interactif](#interactive-rebase) ci-dessus pour savoir comment résoudre ces conflits.
Maintenant, créons une nouvelle branche pour le bug #14, aussi basée sur master :
Maintenant, créons une nouvelle branche pour le bug #14, aussi basée sur main :
```sh
(21)$ git checkout master
(master)$ git checkout -b 14
(21)$ git checkout main
(main)$ git checkout -b 14
(14)$
```
@ -743,7 +743,7 @@ où `upstream` est le dépôt distant depuis lequel vous voulez mettre à jour.
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 :
```sh
(master)$ git checkout -b ma-branche
(main)$ git checkout -b ma-branche
(ma-branceh)$ git branch
(ma-branche)$ touch foo.txt
(ma-branche)$ ls
@ -773,31 +773,31 @@ Date: Tue Jul 29 13:14:46 2014 -0400
Correction #6: Push de force après avoir édité les commits
```
Maintenant, revenons sur master et supprimons notre branche "par accident" :
Maintenant, revenons sur main et supprimons notre branche "par accident" :
```sh
(ma-branche)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
(ma-branche)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch ma-branche (was 4e3cd85).
(master)$ echo oh non, j'ai supprimé ma branche !
(main)$ echo oh non, j'ai supprimé ma branche !
oh non, j'ai supprimé ma branche !
```
À cette étape, vous devriez devenir familier avec `reflog`, un logueur amélioré. Il stocke l'historique de toutes les actions dans le dépôt :
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from ma-branche to master
(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from ma-branche to main
4e3cd85 HEAD@{1}: commit: ajout de foo.txt
69204cd HEAD@{2}: checkout: moving from master to ma-branche
69204cd HEAD@{2}: checkout: moving from main to ma-branche
```
Comme vous pouvez le remarquer, nous avons le hash du commit de notre branche supprimée. Voyons voir si nous pouvons restaurer notre branche supprimée.
```sh
(master)$ git checkout -b ma-branche-help
(main)$ git checkout -b ma-branche-help
Switched to a new branch 'ma-branche-help'
(ma-branche-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 ajout de foo.txt
@ -812,25 +812,25 @@ Voilà ! Nous avons récupéré notre fichier supprimé. `git reflog` est aussi
Pour supprimer une branche distante :
```sh
(master)$ git push origin --delete ma-branche
(main)$ git push origin --delete ma-branche
```
Vous pouvez aussi faire :
```sh
(master)$ git push origin :ma-branche
(main)$ git push origin :ma-branche
```
Pour supprimer une branche locale :
```sh
(master)$ git branch -d ma-branche
(main)$ git branch -d ma-branche
```
Pour supprimer une branche locale qui *n'a pas* été fusionnée vers la branche actuelle ou une branche distante :
```sh
(master)$ git branch -D ma-branche
(main)$ git branch -D ma-branche
```
### Je veux supprimer plusieurs branches
@ -838,7 +838,7 @@ Pour supprimer une branche locale qui *n'a pas* été fusionnée vers la branche
Admettons que vous voulez supprimer toutes les branches qui commencent par `fix/` :
```sh
(master)$ git branch | grep 'fix/' | xargs git branch -d
(main)$ git branch | grep 'fix/' | xargs git branch -d
```
### Je veux renommer une branche
@ -846,13 +846,13 @@ Admettons que vous voulez supprimer toutes les branches qui commencent par `fix/
Je veux renommer la branche actuelle (locale) :
```sh
(master)$ git branch -m nouveau-nom
(main)$ git branch -m nouveau-nom
```
Pour renommer une autre branche (locale) :
```sh
(master)$ 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>
@ -861,13 +861,13 @@ Pour renommer une autre branche (locale) :
Pour commencer, récupérez toutes les branches depuis le dépôt distant :
```sh
(master)$ git fetch --all
(main)$ git fetch --all
```
Admettons que vous souhaitez vous déplacer sur `daves` depuis le dépôt distant :
```sh
(master)$ git checkout --track origin/daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
```
@ -920,14 +920,14 @@ En vérifiant vos branches distantes, vous pouvez voir lesquelles d'entre-elles
```sh
$ git branch -r
origin/HEAD -> origin/gh-pages
origin/master
origin/main
```
Pour changer cela afin que `origin/HEAD` suive `origin/master`, vous pouvez lancer cette commande :
Pour changer cela afin que `origin/HEAD` suive `origin/main`, vous pouvez lancer cette commande :
```sh
$ git remote set-head origin --auto
origin/HEAD set to master
origin/HEAD set to main
```
### J'ai fait des modifications sur la mauvaise branche
@ -957,10 +957,10 @@ Il se peut que vous avez fait une fusion ou un rebase sur votre branche actuelle
Malheureusement, vous devez pousser de force si vous souhaitez que ces modifications soient répercutées sur la branche distante. C'est parce que vous avez changé l'historique. La branche distante n'acceptera pas les modifications, sauf si vous poussez de force. C'est l'une des principales raisons pour lesquelles de nombreuses personnes utilisent un flux de travail à base de fusions plutôt qu'un flux de travail à base de rebase : les grandes équipes peuvent avoir des problèmes avec les développeurs qui poussent de force. Utilisez ceci avec prudence. Une façon plus sûre d'utiliser rebase est de ne pas du tout refléter vos modifications sur la branche distante, mais plutôt de procéder de la manière suivante :
```sh
(master)$ git checkout ma-branche
(ma-branche)$ git rebase -i master
(ma-branche)$ git checkout master
(master)$ git merge --ff-only ma-branche
(main)$ git checkout ma-branche
(ma-branche)$ git rebase -i main
(ma-branche)$ git checkout main
(main)$ git merge --ff-only ma-branche
```
Pour plus d'informations, visitez [ce thread de SO](https://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push).
@ -968,23 +968,23 @@ Pour plus d'informations, visitez [ce thread de SO](https://stackoverflow.com/qu
<a name="interactive-rebase"></a>
### J'ai besoin de combiner des commits
Admettons que vous êtes en train de travailler sur une branche qui sera ou est dans une demande de fusion vers `master`. Dans le cas le plus simple, il suffit de combiner *tous* vos commits en un seul et vous vous fichez des timestamps des commits, vous pouvez faire un reset et recommiter. Assurez-vous que la branche master est à jour et que toutes vos modifications sont commitées, puis faites :
Admettons que vous êtes en train de travailler sur une branche qui sera ou est dans une demande de fusion vers `main`. Dans le cas le plus simple, il suffit de combiner *tous* vos commits en un seul et vous vous fichez des timestamps des commits, vous pouvez faire un reset et recommiter. Assurez-vous que la branche main est à jour et que toutes vos modifications sont commitées, puis faites :
```sh
(ma-branche)$ git reset --soft master
(ma-branche)$ git reset --soft main
(ma-branche)$ git commit -am "Nouvelle fonctionnalité géniale"
```
Si vous voulez plus de contrôle, et également conserver les timestamps, vous devez faire ce qu'on appelle un rebase interactif :
```sh
(ma-branche)$ git rebase -i master
(ma-branche)$ git rebase -i main
```
Si vous ne travaillez pas par rapport à une autre branche, vous allez devoir `rebase` relativement à votre `HEAD`. Si vous voulez combiner les 2 derniers commits par exemple, vous allez devoir `rebase` par rapport à `HEAD~2`. Pour les 3 derniers, `HEAD~3`, etc.
```sh
(master)$ git rebase -i HEAD~2
(main)$ git rebase -i HEAD~2
```
Après avoir lancé votre commande `rebase`, vous verrez quelque chose dans le genre dans votre éditeur de texte :
@ -1044,7 +1044,7 @@ Nouvelles fonctionnalités encore plus géniales
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
# modified: README.md
@ -1055,20 +1055,20 @@ Nouvelles fonctionnalités encore plus géniales
Si tout se passe bien, vous devriez voir quelque chose comme ceci :
```sh
(master)$ Successfully rebased and updated refs/heads/master.
(main)$ Successfully rebased and updated refs/heads/main.
```
#### Stratégie de fusion sûre
`--no-commit` fait une fusion mais prétend que la fusion a échoué et ne commit pas automatiquement, laissant la chance à l'utilisateur d'inspecter plus et de bidouiller plus les résultats de la fusion avant de commiter. `no-ff` garde une preuve qu'une branche de fonctionnalité a auparavant existé, gardant ainsi l'historique du projet consistant :
```sh
(master)$ git merge --no-ff --no-commit ma-branche
(main)$ git merge --no-ff --no-commit ma-branche
```
#### J'ai besoin de fusionner deux branches en un seul commit
```sh
(master)$ git merge --squash ma-branche
(main)$ git merge --squash ma-branche
```
<a name="rebase-unpushed-commits"></a>
@ -1077,7 +1077,7 @@ Si tout se passe bien, vous devriez voir quelque chose comme ceci :
Parfois, vous avez plusieurs commits en cours que vous souhaitez combiner avant de les pousser sur l'upstream. Vous ne voulez pas combiner des commits qui ont déjà été poussés sur l'upstream par accident, car quelqu'un d'autre a peut-être déjà effectué des commits qui y font référence :
```sh
(master)$ git rebase -i @{u}
(main)$ git rebase -i @{u}
```
Cela fera un rebase interactif que liste seulement les commits que vous n'avez pas poussé, afin que cela soit plus sûr de réordonner/corriger/combiner n'importe lesquels de la liste.
@ -1094,26 +1094,26 @@ Cette commande est disponible dans Git depuis les versions >= 1.7.4
### J'ai besoin de mettre à jour le commit parent de ma branche
Admettons que vous avez une branche master, une branche feature-1 créée à partir de master, et une branche feature-2 créée à partir de feature-1, puis que le commit parent de feature-2 n'est plus le bon (il devrait être celui correspondant au HEAD de feature-1, étant donné que notre branche a été créée à partir de celui-ci). Vous pouvez réparer ça avec `git rebase --onto` :
Admettons que vous avez une branche main, une branche feature-1 créée à partir de main, et une branche feature-2 créée à partir de feature-1, puis que le commit parent de feature-2 n'est plus le bon (il devrait être celui correspondant au HEAD de feature-1, étant donné que notre branche a été créée à partir de celui-ci). Vous pouvez réparer ça avec `git rebase --onto` :
```sh
(feature-2)$ git rebase --onto feature-1 <le premier commit dans votre branche feature-2 que vous ne voulez pas ramene> feature-2
```
Cela peut vous venir en aide dans les situations délicates où vous avez une fonctionnalité créée sur la base d'une autre fonctionnalité qui n'a pas encore été fusionnée, et qu'une correction de bug sur la branche feature-1 a besoin d'être reflétée sur votre branche feature-2.
Cela peut vous venir en aide dans les situations délicates où vous avez une fonctionnalité créée sur la base d'une autre fonctionnalité qui n'a pas encore été fusionnée, et qu'une correction de bug sur la branche feature-1 a besoin d'être reflétée sur votre branche feature-2.
### Vérifier si tous les commits d'une branche sont fusionnés
Pour vérifier si tous les commits d'une branche sont fusionnés sur une autre branche, vous devriez comparer les HEAD (ou n'importe quel autre commit) de ces branches :
```sh
(master)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
```
Cela vous dira si des commits sont dans l'une mais pas dans l'autre, et vous donnera une liste de tout ce qui n'est pas commun aux deux branches. Une alternative est de faire ceci :
```sh
(master)$ git log master ^feature/120-on-scroll --no-merges
(main)$ git log main ^feature/120-on-scroll --no-merges
```
### Problèmes possibles avec les rebase interactifs
@ -1128,7 +1128,7 @@ noop
Cela signifie que vous êtes en train de rebaser par rapport à une branche qui a un commit identique, ou qui est *en avance* par rapport à votre branche actuelle. Vous pouvez essayer :
* de vous assurez que votre branche master est là où elle devrait être
* de vous assurez que votre branche main est là où elle devrait être
* de rebaser par rapport à `HEAD~2` ou plus tôt à la place
<a name="merge-conflict"></a>
@ -1163,7 +1163,7 @@ Vous aurez besoin de résoudre les différences entre le code qui fut ajouté da
Si vous voulez garder la version du code d'une des branches, vous pouvez utiliser `--ours` ou `--theirs` :
```sh
(master*)$ git checkout --ours README.md
(main*)$ git checkout --ours README.md
```
- Quand vous *fusionnez*, utilisez `--ours` pour garder les modifications de la branche locale, ou `--theirs` pour garder les modifications de l'autre branche.
@ -1172,7 +1172,7 @@ Si vous voulez garder la version du code d'une des branches, vous pouvez utilise
Si les fusions sont plus complexes, vous pouvez utiliser un éditeur de diff visuel :
```sh
(master*)$ git mergetool -t opendiff
(main*)$ git mergetool -t opendiff
```
Après avoir résolu tous les conflits et testé votre code, faite un `git add` sur les fichiers que vous avez modifiés, puis continuez le rebase avec `git rebase --continue` :
@ -1356,7 +1356,7 @@ $ git push <remote> :refs/tags/<nom_du_tag>
<a name="recover-tag"></a>
### Récupérer un tag supprimé
Si vous voulez récupérer un tag qui a déjà été supprimé, vous pouvez le faire en suivant ces étapes :
Si vous voulez récupérer un tag qui a déjà été supprimé, vous pouvez le faire en suivant ces étapes :
Tout d'abord, vous devez retrouver le tag inaccessible en question :
```sh
@ -1384,7 +1384,7 @@ From github.com:foo/bar
### Exporter un dépôt comme fichier Zip
```sh
$ git archive --format zip --output /full/path/to/zipfile.zip master
$ git archive --format zip --output /full/path/to/zipfile.zip main
```
### Pousser une branche et un tag qui ont le même nom
@ -1414,21 +1414,21 @@ $ git push origin refs/tags/<nom-du-tag>
### Je veux changer la capitalisation du nom d'un fichier, sans changer son contenu
```sh
(master)$ git mv --force monFichier MonFichier
(main)$ git mv --force monFichier MonFichier
```
### Je veux écraser des fichiers locaux en faisant un git pull
```sh
(master)$ git fetch --all
(master)$ git reset --hard origin/master
(main)$ git fetch --all
(main)$ git reset --hard origin/main
```
<a href="remove-from-git"></a>
### Je veux retirer un fichier de Git mais garder le fichier
```sh
(master)$ git rm --cached log.txt
(main)$ git rm --cached log.txt
```
### Je veux rétablir un fichier à une version spécifique
@ -1436,13 +1436,13 @@ $ git push origin refs/tags/<nom-du-tag>
Supposons que le hash du commit que vous voulez est `c5f567` :
```sh
(master)$ git checkout c5f567 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567 -- file1/to/restore file2/to/restore
```
Si vous voulez rétablir les changements effectués un commit avant `c5f567`, passez le hash du commit comme étant `c5f567~1` :
```sh
(master)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
```
### Je veux lister les changements d'un fichier spécifique entre deux commits ou branches
@ -1456,7 +1456,7 @@ $ git diff HEAD:path_to_file/file c5f567:path_to_file/file
Il en est de même pour les branches :
```sh
$ git diff master:path_to_file/file staging:path_to_file/file
$ git diff main:path_to_file/file staging:path_to_file/file
```
### Je veux que Git ignore les changements d'un fichier spécifique
@ -1579,21 +1579,21 @@ Donc, vous êtes fichu - vous avez `reset` quelque chose, ou vous avez fusionné
C'est là qu'intervient `git reflog`. `reflog` garde trace de tous les changements du bout de la branche, même si ce dernier n'est pas référencé par une branche ou un tag. Fondamentalement, chaque fois que le HEAD change, une nouvelle entrée est ajoutée au reflog. Cela marche seulement pour les dépôts locaux, malheureusement, et ne trace que les mouvements (pas les changements d'un fichier qui n'ont été enregistrés nulle part, par exemple).
```sh
(master)$ git reflog
(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
```
Le `reflog` ci-dessus indique un déplacement depuis master vers la branche 2.2 et l'inverse. À partir de là, il y a un hard `reset` vers un commit plus vieux. La dernière activité est représentée en haut et intitulée `HEAD@{0}`.
Le `reflog` ci-dessus indique un déplacement depuis main vers la branche 2.2 et l'inverse. À partir de là, il y a un hard `reset` vers un commit plus vieux. La dernière activité est représentée en haut et intitulée `HEAD@{0}`.
Si il s'avère que vous êtes accidentellement revenu en arrière, le reflog contiendra le commit sur lequel pointait master (0254ea7) avant que vous ne supprimiez 2 commits par accident.
Si il s'avère que vous êtes accidentellement revenu en arrière, le reflog contiendra le commit sur lequel pointait main (0254ea7) avant que vous ne supprimiez 2 commits par accident.
```sh
$ git reset --hard 0254ea7
```
En utilisant `git reset`, il est ensuite possible de changer master vers le commit vers lequel il pointait. Cela vous donne de la sûreté dans le cas où l'historique a été changé par accident.
En utilisant `git reset`, il est ensuite possible de changer main vers le commit vers lequel il pointait. Cela vous donne de la sûreté dans le cas où l'historique a été changé par accident.
(copié et édité depuis [Source](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)).

View File

@ -262,18 +262,18 @@ Git で CLI からプルリクエストを送る方法はありません([hub]
通常はリモートの名前に `upstream` を使います。
```sh
$ (master) git remote add upstream <link-to-original-repository>
# $ (master) git remote add upstream git@github.com:k88hudson/git-flight-rules.git
$ (main) git remote add upstream <link-to-original-repository>
# $ (main) git remote add upstream git@github.com:k88hudson/git-flight-rules.git
```
これで `upstream` から最新版を取得できるようになりました。
```sh
$ (master) git fetch upstream
$ (master) git merge upstream/master
$ (main) git fetch upstream
$ (main) git merge upstream/main
# コマンド一つでもできる
$ (master) git pull upstream master
$ (main) git pull upstream main
```
## コミットの編集
@ -285,7 +285,7 @@ $ (master) git pull upstream master
現在の HEAD の最新のコミット内容は次のように表示できます。
```sh
(master)$ git show
(main)$ git show
```
もしくは次の通りです。
@ -431,13 +431,13 @@ Git は数日間のログを全て残してくれているからです。
(安全なのは `git reset --keep` を使うことです。)
```sh
(master)$ git reflog
(main)$ git reflog
```
過去のコミットとリセットに対応するコミットが表示されるので、復元したいコミットの SHA を選んでリセットします。
```sh
(master)$ git reset --hard SHA1234
(main)$ git reset --hard SHA1234
```
これで大丈夫です。
@ -525,9 +525,9 @@ bfg-repo-cleaner を使うには Java が必要です。
特定のファイルを削除する場合は次のようにします。
```sh
(master)$ git rm path/to/filetoremove
(master)$ git commit -m "Commit removing filetoremove"
(master)$ java -jar ~/Downloads/bfg.jar --delete-files filetoremove
(main)$ git rm path/to/filetoremove
(main)$ git commit -m "Commit removing filetoremove"
(main)$ java -jar ~/Downloads/bfg.jar --delete-files filetoremove
```
なお、bfg を使うときは、ファイルがサブディレクトリにあってもそのままのファイル名を入力することに注意してください。
@ -535,9 +535,9 @@ bfg-repo-cleaner を使うには Java が必要です。
パターンからファイルを削除することもできます。例えば次の通りです。
```sh
(master)$ git rm *.jpg
(master)$ git commit -m "Commit removing *.jpg"
(master)$ java -jar ~/Downloads/bfg.jar --delete-files *.jpg
(main)$ git rm *.jpg
(main)$ git commit -m "Commit removing *.jpg"
(main)$ java -jar ~/Downloads/bfg.jar --delete-files *.jpg
```
bfg は最新のコミットにあるファイルには影響しません。
@ -554,7 +554,7 @@ bfg は最新のコミットにあるファイルには影響しません。
パターンにマッチしたファイルの履歴が全ての履歴とブランチから削除されます。
```sh
(master)$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch filepattern' --prune-empty --tag-name-filter cat -- --all
(main)$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch filepattern' --prune-empty --tag-name-filter cat -- --all
```
ここで使っている `--tag-name-filter cat` は煩雑ですが、このように `cat` を使うのが元のタグを新しいコミットにつける最も簡単な方法です。
@ -567,23 +567,23 @@ bfg は最新のコミットにあるファイルには影響しません。
最後のステップとして、必要に応じて Git ガベージコレクションで .git フォルダの容量を最小化してから、強制プッシュします。
```sh
(master)$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
(master)$ git push origin --force --tags
(main)$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
(main)$ git push origin --force --tags
```
リポジトリの履歴を全て書き換えているので、`git push` の量が膨大すぎて `“The remote end hung up unexpectedly”` というエラーが返るかもしれません。
その場合は Git の post buffer を増やしてみます。
```sh
(master)$ git config http.postBuffer 524288000
(master)$ git push --force
(main)$ git config http.postBuffer 524288000
(main)$ git push --force
```
うまくいかない場合は、コミットを手作業で小分けにしてプッシュします。
プッシュが成功するまで、`<number>` を増やしながら次のコマンドを試してください。
```sh
(master)$ git push -u origin HEAD~<number>:refs/head/master --force
(main)$ git push -u origin HEAD~<number>:refs/head/main --force
```
プッシュが成功したら、通常の`git push` が 成功するまで `<number>` を徐々に減らしてください。
@ -746,7 +746,7 @@ $ git stash pop
```sh
(my-branch)$ git reset --hard
# または
(master)$ git checkout -f
(main)$ git checkout -f
```
次のコマンドは `git add` でステージした全ファイルのステージを取り消します。
@ -889,7 +889,7 @@ $ git checkout -b <branch> <SHA1_OF_COMMIT>
間違ったプルの前に HEAD が参照していたものを表示します。
```sh
(master)$ git reflog
(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here
```
@ -920,7 +920,7 @@ $ git reset --hard c5bc55a
origin と同じ状態にリセットする(リモートと同じ状態にする)方法の一つは次の通りです。
```sh
(master)$ git reset --hard origin/my-branch
(main)$ git reset --hard origin/my-branch
```
<a name="commit-wrong-branch"></a>
@ -929,13 +929,13 @@ origin と同じ状態にリセットする(リモートと同じ状態にす
マスターブランチにいたまま、新しいブランチを作成してください。
```sh
(master)$ git branch my-branch
(main)$ git branch my-branch
```
マスターブランチを直前のコミットにリセットします。
```sh
(master)$ git reset --hard HEAD^
(main)$ git reset --hard HEAD^
```
ここで `HEAD^``HEAD^1` の短縮形で、`HEAD` の第一の親を表します。
@ -949,14 +949,14 @@ origin と同じ状態にリセットする(リモートと同じ状態にす
例えば、マスターブランチを差し戻したいコミットのハッシュが `a13b85e` なら、次のようにします。
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
作業に戻るため、新しいブランチにチェックアウトしましょう。
```sh
(master)$ git checkout my-branch
(main)$ git checkout my-branch
```
<a name="keep-whole-file"></a>
@ -1005,7 +1005,7 @@ HEAD is now at a13b85e
マスターブランチにいるとして、`git log` でコミットが二つ表示されるとします。
```sh
(master)$ git log
(main)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
@ -1031,14 +1031,14 @@ Date: Tue Jul 21 01:12:48 2014 -0400
まず、次のようにしてマスターブランチをあるべきコミット `a13b85e` までリセットします。
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
これで、バグ #21 に対応する新しいブランチを作成できます。
```sh
(master)$ git checkout -b 21
(main)$ git checkout -b 21
(21)$
```
@ -1055,8 +1055,8 @@ HEAD is now at a13b85e
次に、#14 に対応する、マスターに紐づいたブランチを作成しましょう。
```sh
(21)$ git checkout master
(master)$ git checkout -b 14
(21)$ git checkout main
(main)$ git checkout -b 14
(14)$
```
@ -1087,7 +1087,7 @@ $ git fetch -p upstream
新しくブランチを作り、ファイルを新規作成したとします。
```sh
(master)$ git checkout -b my-branch
(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
@ -1120,12 +1120,12 @@ Date: Tue Jul 29 13:14:46 2014 -0400
マスターに戻って、「間違って」ブランチを削除してみます。
```sh
(my-branch)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
(my-branch)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(master)$ echo oh noes, deleted my branch!
(main)$ echo oh noes, deleted my branch!
oh noes, deleted my branch!
```
@ -1133,17 +1133,17 @@ oh noes, deleted my branch!
これはリポジトリの全ての操作履歴を保存しています。
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to master
(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to main
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from master to my-branch
69204cd HEAD@{2}: checkout: moving from main to my-branch
```
このように、削除してしまったブランチのコミットが表示されています。
削除したブランチを復元してみましょう。
```sh
(master)$ git checkout -b my-branch-help
(main)$ git checkout -b my-branch-help
Switched to a new branch 'my-branch-help'
(my-branch-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 foo.txt added
@ -1159,25 +1159,25 @@ README.md foo.txt
リモートブランチを削除するには次を実行します。
```sh
(master)$ git push origin --delete my-branch
(main)$ git push origin --delete my-branch
```
次のようにもできます。
```sh
(master)$ git push origin :my-branch
(main)$ git push origin :my-branch
```
ローカルブランチを削除するには次の通りです。
```sh
(master)$ git branch -d my-branch
(main)$ git branch -d my-branch
```
現在のブランチか upstream にマージ**されていない**ブランチを削除するには次のようにします。
```sh
(master)$ git branch -D my-branch
(main)$ git branch -D my-branch
```
### 複数のブランチを削除したい
@ -1185,7 +1185,7 @@ README.md foo.txt
名前が `fix/` で始まるブランチを全て削除したいときは次の通りです。
```sh
(master)$ git branch | grep 'fix/' | xargs git branch -d
(main)$ git branch | grep 'fix/' | xargs git branch -d
```
### ブランチの名前を変更したい
@ -1193,19 +1193,19 @@ README.md foo.txt
現在の(ローカル)ブランチの名前を変更するには次を実行します。
```sh
(master)$ git branch -m new-name
(main)$ git branch -m new-name
```
現在いるブランチと異なる(ローカル)ブランチの名前を変更するには次のようにします。
```sh
(master)$ git branch -m old-name new-name
(main)$ git branch -m old-name new-name
```
古い名前(`old-name`)のリモートブランチを削除し、新しい名前(`new-name`)のブランチをプッシュするには次の通りです。
```sh
(master)$ 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>
@ -1214,13 +1214,13 @@ README.md foo.txt
まず、リモートから全ブランチを取得します。
```sh
(master)$ git fetch --all
(main)$ git fetch --all
```
リモートブランチ `daves` にチェックアウトしたいとします。
```sh
(master)$ git checkout --track origin/daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
```
@ -1274,14 +1274,14 @@ $ git branch -u [remotename]/[branch] [local-branch]
```sh
$ git branch -r
origin/HEAD -> origin/gh-pages
origin/master
origin/main
```
`origin/HEAD``origin/master` を追跡するよう設定し直すには、次を実行します。
`origin/HEAD``origin/main` を追跡するよう設定し直すには、次を実行します。
```sh
$ git remote set-head origin --auto
origin/HEAD set to master
origin/HEAD set to main
```
### 間違ったブランチを編集してしまった
@ -1319,10 +1319,10 @@ Git は危険な操作の前に HEAD が指すものを変数 `ORIG_HEAD` に保
リベースの安全な使い方は、リモートには編集を反映させずに、代わりに次を実行することです。
```sh
(master)$ git checkout my-branch
(my-branch)$ git rebase -i master
(my-branch)$ git checkout master
(master)$ git merge --ff-only my-branch
(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch
```
詳しくは[この StackOverflow スレッド](https://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push)を参照してください。
@ -1330,27 +1330,27 @@ Git は危険な操作の前に HEAD が指すものを変数 `ORIG_HEAD` に保
<a name="interactive-rebase"></a>
### コミットを統合したい
`master` ブランチにプルリクエストを送る、あるいはこれから送るつもりのブランチで作業しているとします。
`main` ブランチにプルリクエストを送る、あるいはこれから送るつもりのブランチで作業しているとします。
最も単純なケースとして、タイムスタンプを気にせずコミット**全部**を一つにまとめたいとします。
この場合はリセットと再コミットを行います。
マスターブランチが最新版で、編集がすべてコミットされていることを確認した上で、次を実行してください。
```sh
(my-branch)$ git reset --soft master
(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"
```
もっと細かく設定し、タイムスタンプも残したい場合は、対話的リベースを使います。
```sh
(my-branch)$ git rebase -i master
(my-branch)$ git rebase -i main
```
別のブランチで作業しているわけではない場合、`HEAD` に対してリベースする必要があります。
たとえば直近二件のコミットを圧縮 (squash) したい場合は `HEAD~2`、直近三件なら `HEAD~3` です。
```sh
(master)$ git rebase -i HEAD~2
(main)$ git rebase -i HEAD~2
```
対話的リベースのコマンドを実行したら、テキストエディタに次のように表示されます。
@ -1411,7 +1411,7 @@ Newer, awesomer features
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
# modified: README.md
@ -1422,7 +1422,7 @@ Newer, awesomer features
うまくいくと次のように表示されるはずです。
```sh
(master)$ Successfully rebased and updated refs/heads/master.
(main)$ Successfully rebased and updated refs/heads/main.
```
#### 安全なマージの方法
@ -1432,13 +1432,13 @@ Newer, awesomer features
オプション `--no-ff` はフィーチャーブランチが存在したことを記録に残しておき、プロジェクト履歴の一貫性を保ちます。
```sh
(master)$ git merge --no-ff --no-commit my-branch
(main)$ git merge --no-ff --no-commit my-branch
```
#### ブランチを一つのコミットにまとめたい場合
```sh
(master)$ git merge --squash my-branch
(main)$ git merge --squash my-branch
```
<a name="rebase-unpushed-commits"></a>
@ -1448,7 +1448,7 @@ Newer, awesomer features
すでに upstream にプッシュされたコミットは、誰かがそれを参照するコミットをしている可能性があるので、それは統合しないでおきたいとします。
```sh
(master)$ git rebase -i @{u}
(main)$ git rebase -i @{u}
```
上を実行すると対話的リベースが始まりますが、一覧にはまだプッシュされていないコミットだけが表示されます。
@ -1482,14 +1482,14 @@ Newer, awesomer features
ブランチの全コミットが別のブランチにマージされているか確認するには、それぞれのブランチの headあるいは任意のコミットの間の差分を表示します。
```sh
(master)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
```
一方のブランチにしかないコミットがあるか表示され、ブランチ間で共有されていないコミットの一覧がわかります。
もう一つの方法は次の通りです。
```sh
(master)$ git log master ^feature/120-on-scroll --no-merges
(main)$ git log main ^feature/120-on-scroll --no-merges
```
### 対話的リベースで起こりうる問題
@ -1542,7 +1542,7 @@ Changes not staged for commit:
一方のブランチの版のコードを残したい場合は、`--ours` あるいは `--theirs` を指定します。
```sh
(master*)$ git checkout --ours README.md
(main*)$ git checkout --ours README.md
```
- *マージする*場合、ローカルブランチの編集を残したいとき `--ours` を指定し、他方の編集を残したいとき `--theirs` を指定します。
@ -1551,7 +1551,7 @@ Changes not staged for commit:
マージがもっと複雑なときは、ビジュアル差分エディタを使うとよいです。
```sh
(master*)$ git mergetool -t opendiff
(main*)$ git mergetool -t opendiff
```
コンフリクトを全て解消し、コードのテストが済んだら、`git add ` で編集をステージし、`git rebase --continue` でリベースを再開します。
@ -1806,7 +1806,7 @@ From github.com:foo/bar
### リポジトリを zip ファイルとしてエクスポートしたい
```sh
$ git archive --format zip --output /full/path/to/zipfile.zip master
$ git archive --format zip --output /full/path/to/zipfile.zip main
```
### 同じ名前のブランチとタグをプッシュしたい
@ -1837,21 +1837,21 @@ $ git push origin refs/tags/<tag-name>
### ファイルの内容は変えずに、ファイル名の大文字・小文字を変更したい
```sh
(master)$ git mv --force myfile MyFile
(main)$ git mv --force myfile MyFile
```
### git pull してローカルのファイルを上書きしたい
```sh
(master)$ git fetch --all
(master)$ git reset --hard origin/master
(main)$ git fetch --all
(main)$ git reset --hard origin/main
```
<a href="remove-from-git"></a>
### ファイルを残しつつ Git から削除したい
```sh
(master)$ git rm --cached log.txt
(main)$ git rm --cached log.txt
```
### ファイルを特定の版まで差し戻したい
@ -1859,13 +1859,13 @@ $ git push origin refs/tags/<tag-name>
差し戻したいコミットのハッシュが `c5f567` なら、次を実行します。
```sh
(master)$ git checkout c5f567 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567 -- file1/to/restore file2/to/restore
```
差し戻したいコミットが c5f567 の一つ前なら、コミットハッシュに `c5f567~1` を指定します。
```sh
(master)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
```
### 特定のファイルのコミット間・ブランチ間の差分を表示したい
@ -1879,7 +1879,7 @@ $ git diff HEAD:path_to_file/file c5f567:path_to_file/file
ブランチでも同様です。
```sh
$ git diff master:path_to_file/file staging:path_to_file/file
$ git diff main:path_to_file/file staging:path_to_file/file
```
### 特定のファイルの変更を無視したい
@ -1901,7 +1901,7 @@ $ git update-index --no-assume-unchanged file-to-stop-ignoring
コマンド [git-bisect](https://git-scm.com/docs/git-bisect) は、Git 履歴を二分探索してバグをもたらしたコミットを探します。
いま `master` ブランチにいるとして、失敗をやらかしたコミットを探してみましょう。
いま `main` ブランチにいるとして、失敗をやらかしたコミットを探してみましょう。
次のコマンドで二分探索を始めます。
```sh
@ -1967,7 +1967,7 @@ OS X と Linux では、Git 設定ファイルは ```~/.gitconfig``` に保存
wip = rebase -i @{u}
zap = fetch -p
day = log --reverse --no-merges --branches=* --date=local --since=midnight --author=\"$(git config --get user.name)\"
delete-merged-branches = "!f() { git checkout --quiet master && git branch --merged | grep --invert-match '\\*' | xargs -n 1 git branch --delete; git checkout --quiet @{-1}; }; f"
delete-merged-branches = "!f() { git checkout --quiet main && git branch --merged | grep --invert-match '\\*' | xargs -n 1 git branch --delete; git checkout --quiet @{-1}; }; f"
```
### 空のディレクトリをリポジトリに加えたい
@ -2079,13 +2079,13 @@ HEAD が変更される際は基本的に reflog に記録が追加されます
ただ、残念ながら機能するのはローカルリポジトリのみで、記録するのは変化だけです(たとえば、どこにも記録されていないファイルへの変更は記録されません)。
```sh
(master)$ git reflog
(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
```
上の reflog には、master から 2.2 へのチェックアウトが表示されています。
上の reflog には、main から 2.2 へのチェックアウトが表示されています。
それから古いコミットへの hard reset があります。
最新のアクティビティは一番上に `HEAD@{0}` のラベルで表示されます。

View File

@ -5,18 +5,18 @@
#### flight rules 가 뭐야?
뭔가 잘못 됐을 때 뭘 해야할지에 대한 우주비행사를 위한 가이드 (여기선 깃을 쓰는 개발자를 위한)
뭔가 잘못 됐을 때 뭘 해야할지에 대한 우주비행사를 위한 가이드 (여기선 깃을 쓰는 개발자를 위한)
> *Flight Rules* 는 어떤 문제 X가 발생한 이유와 그 단계의 매뉴얼에서 어렵사리 얻은 지식이에요. 기본적으로 각 시나리오의 매우 자세하고 구체적인 운영 절차랍니다. [...]
> NASA는 수성(Mercury) 시대 때 지상팀에서 처음으로 "lessons learned" 이란 것을 모았는데 수천개의 문제의 상황들, 부서진 해치 손잡이로 인한 엔진 고장부터 컴퓨터 문제 그리고 그 해답까지, 1960년대 초부터 우리의 실수들, 재앙들, 해결책 등이 목록화 돼있어요.
> NASA는 수성(Mercury) 시대 때 지상팀에서 처음으로 "lessons learned" 이란 것을 모았는데 수천개의 문제의 상황들, 부서진 해치 손잡이로 인한 엔진 고장부터 컴퓨터 문제 그리고 그 해답까지, 1960년대 초부터 우리의 실수들, 재앙들, 해결책 등이 목록화 돼있어요.
— Chris Hadfield, *인생을 위한 우주비행사의 가이드*.
#### 이 문서의 규칙
명확하게 하기 위해 이 문서의 모든 예제는 현재 브랜치를 표시하고 스테이지에 변경이 있는지를 나타내기 위해 커스텀 된 배시 프롬프트를 써요. 브랜치는 괄호 안에 있고, 브랜치 다음의 *는 스테이지의 변경된 것을 나타내요.
명확하게 하기 위해 이 문서의 모든 예제는 현재 브랜치를 표시하고 스테이지에 변경이 있는지를 나타내기 위해 커스텀 된 배시 프롬프트를 써요. 브랜치는 괄호 안에 있고, 브랜치 다음의 *는 스테이지의 변경된 것을 나타내요.
[![Join the chat at https://gitter.im/k88hudson/git-flight-rules](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/k88hudson/git-flight-rules?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
@ -138,7 +138,7 @@
$ git clone [url]
```
폴더 이름이 리모트 레파지토리 이름과 같이 저장될 거에요.
폴더 이름이 리모트 레파지토리 이름과 같이 저장될 거에요.
복제할 리모트 서버의 연결을 확인하세요.(대부분 인터넷 연결을 확인하란 뜻이에요)
@ -158,10 +158,10 @@ $ git clone [url] name-of-new-folder
`git commit -a` 로 막 커밋을 남기고 내가 뭐라고 안에 적었더라? 한다고 하고. 최근의 커밋을 현재 HEAD에서 볼 수 있어요.
```sh
(master)$ git show
(main)$ git show
```
또는
또는
```sh
$ git log -n1 -p
@ -198,7 +198,7 @@ $ git commit --amend --only -m 'xxxxxxx'
$ git commit --amend --no-edit --author "New Authorname <authoremail@mydomain.com>"
```
대안으로는 `git config --global author.(name|email)`에서 설정을 다시 맞춘 다음
대안으로는 `git config --global author.(name|email)`에서 설정을 다시 맞춘 다음
```sh
$ git commit --amend --reset-author --no-edit
@ -241,8 +241,8 @@ $ git push --force-with-lease [remote] [branch]
(my-branch*)$ git reset --soft HEAD@{1}
```
이 방법은 푸시를 안 했을 때만 동작해요. 푸시를 했으면, 안전한 방법은 `git revert SHAofBadCommit` 한가지 밖이에요.
이 방법은 모든 지난 커밋 변경점으로 되돌아간 새 커밋을 만들 거에요. 또는, 만약 푸시한 브랜치가 리베이스에 안전하다면 (만약 다른 사람이 풀 받지 않는다면), `git push --force-with-lease` 명령어를 쓸수 있어요.
이 방법은 푸시를 안 했을 때만 동작해요. 푸시를 했으면, 안전한 방법은 `git revert SHAofBadCommit` 한가지 밖이에요.
이 방법은 모든 지난 커밋 변경점으로 되돌아간 새 커밋을 만들 거에요. 또는, 만약 푸시한 브랜치가 리베이스에 안전하다면 (만약 다른 사람이 풀 받지 않는다면), `git push --force-with-lease` 명령어를 쓸수 있어요.
더 알고 싶다면, [이 섹션](#deleteremove-last-pushed-commit)을 참고해주세요.
<a name="delete-any-commit"></a>
@ -279,7 +279,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```
일반적으로 강제 푸시를 쓰지 마세요.
새 커밋을 만들어서 푸시하는게 수정된 커밋을 강제로 푸시하는 것보다 훨씬 나아요. 그런 수정된 커밋은 그 브랜치나 다른 자식 브랜치를 쓰는 다른 개발자의 소스 이력과 충돌의 원인이 될거에요.
새 커밋을 만들어서 푸시하는게 수정된 커밋을 강제로 푸시하는 것보다 훨씬 나아요. 그런 수정된 커밋은 그 브랜치나 다른 자식 브랜치를 쓰는 다른 개발자의 소스 이력과 충돌의 원인이 될거에요.
`--force-with-lease` 는 여전히 실패할텐데, 누군가가 같은 브랜치를 쓴다면 변경점을 덮어쓰는 푸시를 할 수도 있어요.
절대로 아무도 같은 브랜치를 안 쓰거나, 절대로 브랜치에 업데이트를 해야할때 `--force` (`-f`) 옵션을 쓸 수 있지만 일반적으론 피하는게 좋아요.
@ -287,18 +287,18 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
<a href="undo-git-reset-hard"></a>
### 하드 리셋을 해버렸는데 되돌리고 싶어
만약 하드 리셋을 했다고 해도 커밋을 돌릴 순 있어요. 깃은 며칠간은 로그를 가지고 있거든요.
만약 하드 리셋을 했다고 해도 커밋을 돌릴 순 있어요. 깃은 며칠간은 로그를 가지고 있거든요.
알아두기 : 이건 커밋을 남겼거나 스테이시같이 백업을 했을 때만 유효해요. `git reset --hard` 은 커밋되지 않은 수정사항을 _다 지울 거에요_, 그러니 조심해서 써야해요. (안전한 방법으론 `git reset --keep` 이 있어요)
```sh
(master)$ git reflog
(main)$ git reflog
```
지난 커밋과 리셋을 위한 커밋을 볼 수 있을 거에요. 돌아가고 싶은 커밋의 SHA 코드를 골라서, 리셋을 해요:
지난 커밋과 리셋을 위한 커밋을 볼 수 있을 거에요. 돌아가고 싶은 커밋의 SHA 코드를 골라서, 리셋을 해요:
```sh
(master)$ git reset --hard SHA1234
(main)$ git reset --hard SHA1234
```
계속 할 수 있을거에요.
@ -308,14 +308,14 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
만약 실수로 머지할 준비가 안된 피쳐 브랜치를 메인 브랜치에 머지했어도 되돌릴 순 있어요.
하지만 문제는 있어요: 머지 커밋은 한개 이상의 부모(보통은 두 개)를 가지게 돼요.
사용하려면
```sh
(feature-branch)$ git revert -m 1 <commit>
```
여기서 -m 1 옵션은 부모 번호 1(머지가 만들어진 브랜치)을 되돌릴 상위 항목으로 선택하라고 해요.
여기서 -m 1 옵션은 부모 번호 1(머지가 만들어진 브랜치)을 되돌릴 상위 항목으로 선택하라고 해요.
알아두기 : 부모 번호는 커밋 식별자가 아니고, 오히려 머지된 커밋이 `Merge: 8e2ce2d 86ac2e7` 이라는 라인을 가지고 있어요.
부모 번호는 이 라인에서 원하는 부모의 1 기반 인덱스이고, 첫번째 식별자는 1, 다음은 2 이렇게 이어져요.
@ -332,7 +332,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
<a name="commit-partial-new-file"></a>
### 전체가 아닌 새 파일만 스테이지에 올리고 싶어
보통은 부분적으로 파일을 스테이지하려면 이렇게 해요:
보통은 부분적으로 파일을 스테이지하려면 이렇게 해요:
```sh
$ git add --patch filename.x
@ -354,7 +354,7 @@ $ git add -N filename.x
<a href="unstaging-edits-and-staging-the-unstaged"></a>
### 아직 스테이지에 안 올라간 변경점을 스테이지에 추가하고, 스테이지에 있는 변경점을 다시 빼고 싶어
이건 좀 꼼수인데요, 스테이지 전인 파일들을 스테이시해서 빼두고선 리셋 할 수 있을거에요. 그 다음 스테이시를 다시 불러와 추가를 해요.
이건 좀 꼼수인데요, 스테이지 전인 파일들을 스테이시해서 빼두고선 리셋 할 수 있을거에요. 그 다음 스테이시를 다시 불러와 추가를 해요.
```sh
$ git stash -k
@ -389,10 +389,10 @@ $ git stash pop
```sh
(my-branch)$ git reset --hard
# or
(master)$ git checkout -f
(main)$ git checkout -f
```
이 방법은 `git add`로 스테이징된 모든 파일이 빠지게 돼요.
이 방법은 `git add`로 스테이징된 모든 파일이 빠지게 돼요.
```sh
$ git reset
@ -431,10 +431,10 @@ $ git clean -fd
```sh
$ git checkout -p
# 날리고 싶은 사항에 y를 적으세요
# 날리고 싶은 사항에 y를 적으세요
```
또다른 전략은 `stash`을 같이 쓰는거에요. 챙겨야 하는 변경점을 스테이시 하고, 작업 중인 영역을 리셋하고, 다시 올바른 변경점으로 재적용해요.
또다른 전략은 `stash`을 같이 쓰는거에요. 챙겨야 하는 변경점을 스테이시 하고, 작업 중인 영역을 리셋하고, 다시 올바른 변경점으로 재적용해요.
```sh
$ git stash -p
@ -476,7 +476,7 @@ $ git checkout .
<a href="i-want-to-discard-all-my-untracked-files"></a>
### 트래킹 안된 파일들 다 지우고 싶어
트래킹 안된 파일들 다 지우고 싶을 땐
트래킹 안된 파일들 다 지우고 싶을 땐
```sh
$ git clean -f
@ -484,7 +484,7 @@ $ git clean -f
## 브랜치
### 모든 브랜치 리스트를 보고 싶어
### 모든 브랜치 리스트를 보고 싶어
로컬 브랜치 다 보기
@ -492,7 +492,7 @@ $ git clean -f
$ git branch
```
리모트 브랜치 다 보기
리모트 브랜치 다 보기
```sh
$ git branch -r
@ -517,12 +517,12 @@ $ git checkout -b <branch> <SHA1_OF_COMMIT>
이건 잘못된 풀을 받기전 HEAD가 어딜 가르키고 있었는지 볼 수 있는 `git reflog`를 써볼 수 있는 기회에요.
```sh
(master)$ git reflog
(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here
```
간단히 원하는 커밋으로 브랜치를 되돌릴 수 있어요:
간단히 원하는 커밋으로 브랜치를 되돌릴 수 있어요:
```sh
$ git reset --hard c5bc55a
@ -535,7 +535,7 @@ $ git reset --hard c5bc55a
서버에 변경점을 푸시 안했는지부터 확인해요.
`git status` 가 오리진보다 몇개의 커밋들이 앞서 있는지 보여줄거에요:
`git status` 가 오리진보다 몇개의 커밋들이 앞서 있는지 보여줄거에요:
```sh
(my-branch)$ git status
@ -548,7 +548,7 @@ $ git reset --hard c5bc55a
오리진(리모트과 같은 상태의)로 맞추는 리셋을 하는 방법 중 하나는:
```sh
(master)$ git reset --hard origin/my-branch
(main)$ git reset --hard origin/my-branch
```
<a name="commit-wrong-branch"></a>
@ -557,17 +557,17 @@ $ git reset --hard c5bc55a
마스터에 있으면서 새 브랜치를 만들어요:
```sh
(master)$ git branch my-branch
(main)$ git branch my-branch
```
마스터 브랜치를 기존 커밋으로 리셋해요:
```sh
(master)$ git reset --hard HEAD^
(main)$ git reset --hard HEAD^
```
`HEAD^``HEAD^1`의 축약인데요. `HEAD^`의 첫번째 부모를 의미하고, 비슷한 `HEAD^2`는 두번째 부모를 의미해요. (머지는 두 부모를 가질 수 있죠)
`HEAD^``HEAD^1`의 축약인데요. `HEAD^`의 첫번째 부모를 의미하고, 비슷한 `HEAD^2`는 두번째 부모를 의미해요. (머지는 두 부모를 가질 수 있죠)
알아두세요 `HEAD^2``HEAD~2`과 같은게 아니에요. (더 자세한 정보는 [이 링크](http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde)를 참고해요 )
@ -576,18 +576,18 @@ $ git reset --hard c5bc55a
예를 들자면, 그 마스터의 커밋의 해쉬가 `a13b85e`라면:
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
새 브랜치로 체크아웃 해서 계속 작업을 해요:
```sh
(master)$ git checkout my-branch
(main)$ git checkout my-branch
```
<a name="keep-whole-file"></a>
### 다른 레퍼런스 같은 곳에서 모든 파일을 유지하고 싶어
### 다른 레퍼런스 같은 곳에서 모든 파일을 유지하고 싶어
수백번의 변경점을 가진 스파이크(아래 알아두기 참고) 작업을 한다고 가정해보죠. 모든 건 동작하고 있고,그 작업을 저장해두기 위해 다른 브랜치로 커밋을 해요:
@ -621,7 +621,7 @@ HEAD is now at a13b85e
그 다음, 평소처럼 커밋해요.
알아두기 : 스파이크 솔루션은 문제를 분석하거나 풀기위해 만들어졌어요. 이 솔루션들은 모두가 문제의 확실한 시각화를 얻고선 평가되고 제거돼요.~ [위키피디아](https://en.wikipedia.org/wiki/Extreme_programming_practices).
알아두기 : 스파이크 솔루션은 문제를 분석하거나 풀기위해 만들어졌어요. 이 솔루션들은 모두가 문제의 확실한 시각화를 얻고선 평가되고 제거돼요.~ [위키피디아](https://en.wikipedia.org/wiki/Extreme_programming_practices).
<a name="cherry-pick"></a>
### 한 브랜치에 다른 브랜치에 남겼어야 하는 커밋을 여러개 남겼어
@ -629,7 +629,7 @@ HEAD is now at a13b85e
마스터 브랜치에 있다고 가정하고 `git log` 해보면 커밋 두개 볼 수 있을거에요:
```sh
(master)$ git log
(main)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
@ -655,14 +655,14 @@ Date: Tue Jul 21 01:12:48 2014 -0400
우선, 마스터 브랜치의 정확한 커밋 (`a13b85e`)으로 리셋해요:
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
그리고, 21번 버그 작업을 위한 새로운 브랜치를 만들수 있어요:
```sh
(master)$ git checkout -b 21
(main)$ git checkout -b 21
(21)$
```
@ -673,17 +673,17 @@ HEAD is now at a13b85e
```
이 지점에서 충돌이 있을 수도 있어요.
어떻게 충돌을 해결할지 [대화형 리베이스 섹션](#interactive-rebase) 안에 있는 [**충돌이 있어**](#merge-conflict) 부분을 참고하세요.
어떻게 충돌을 해결할지 [대화형 리베이스 섹션](#interactive-rebase) 안에 있는 [**충돌이 있어**](#merge-conflict) 부분을 참고하세요.
자 이제 14번 버그 작업을 위해 마스터로 가서 새 브랜치를 만들어요.
```sh
(21)$ git checkout master
(master)$ git checkout -b 14
(21)$ git checkout main
(main)$ git checkout -b 14
(14)$
```
그리고 마지막으로, 14번 버그작업을 위한 커밋을 체리픽해요.
그리고 마지막으로, 14번 버그작업을 위한 커밋을 체리픽해요.
```sh
(14)$ git cherry-pick 5ea5173
@ -707,7 +707,7 @@ $ git fetch -p upstream
주기적으로 리모트으로 푸시한다면, 대부분은 안전해야 해요. 그치만 가끔은 브랜치를 지울 수 있어요. 새 브랜치를 만들고 파일을 하나 만들었다고 해보죠:
```sh
(master)$ git checkout -b my-branch
(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
@ -740,28 +740,28 @@ Date: Tue Jul 29 13:14:46 2014 -0400
이제 다시 마스터로 돌아가 '실수로' 브랜치를 지워보죠.
```sh
(my-branch)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
(my-branch)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(master)$ echo oh noes, deleted my branch!
(main)$ echo oh noes, deleted my branch!
oh noes, deleted my branch!
```
여기에서 업그레이드된 로그 도구인 '리플로그'에 익숙해져야 해요. 리플로그는 레파지토리의 모든 행동의 이력을 다 보관해요.
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to master
(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to main
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from master to my-branch
69204cd HEAD@{2}: checkout: moving from main to my-branch
```
보시다시피 지워진 브랜치의 커밋 해쉬도 볼 수 있어요. 지웠던 브랜치를 살릴 수 있는 지 한번 해보죠.
```sh
(master)$ git checkout -b my-branch-help
(main)$ git checkout -b my-branch-help
Switched to a new branch 'my-branch-help'
(my-branch-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 foo.txt added
@ -776,25 +776,25 @@ README.md foo.txt
리모트 브랜치를 삭제하려면:
```sh
(master)$ git push origin --delete my-branch
(main)$ git push origin --delete my-branch
```
이렇게도:
```sh
(master)$ git push origin :my-branch
(main)$ git push origin :my-branch
```
로컬 브랜치를 삭제하려면:
```sh
(master)$ git branch -d my-branch
(main)$ git branch -d my-branch
```
현재 브랜치나 업스트림에 머지되지 않은 로컬 브랜치를 지우려면:
```sh
(master)$ git branch -D my-branch
(main)$ git branch -D my-branch
```
### 여러개의 브랜치를 지우고 싶어
@ -802,7 +802,7 @@ README.md foo.txt
`fix/`로 시작하는 모든 브랜치들을 지우고 싶다면:
```sh
(master)$ git branch | grep 'fix/' | xargs git branch -d
(main)$ git branch | grep 'fix/' | xargs git branch -d
```
### 브랜치 이름을 바꾸고 싶어
@ -810,28 +810,28 @@ README.md foo.txt
현재 (로컬) 브랜치 이름을 바꾸려면:
```sh
(master)$ git branch -m new-name
(main)$ git branch -m new-name
```
다른 (로컬) 브랜치 이름을 바꾸려면
```sh
(master)$ 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>
### 다른 사람이 작업중인 리모트 브랜치로 체크아웃 하고 싶어
우선, 리모트 레파지토리에서 모든 브랜치를 패치 받아요:
우선, 리모트 레파지토리에서 모든 브랜치를 패치 받아요:
```sh
(master)$ git fetch --all
(main)$ git fetch --all
```
리모트의 `daves`로 체크아웃 하고 싶다고 하면.
```sh
(master)$ git checkout --track origin/daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
```
@ -886,14 +886,14 @@ $ git branch -u [remotename]/[branch] [local-branch]
```sh
$ git branch -r
origin/HEAD -> origin/gh-pages
origin/master
origin/main
```
`origin/HEAD``origin/master`를 트래킹하는 것으로 변경하려면, 이 커맨드로 실행할 수 있어요:
`origin/HEAD``origin/main`를 트래킹하는 것으로 변경하려면, 이 커맨드로 실행할 수 있어요:
```sh
$ git remote set-head origin --auto
origin/HEAD set to master
origin/HEAD set to main
```
### 다른 브랜치에 변경점을 잘못 남겼어
@ -925,14 +925,14 @@ origin/HEAD set to master
리모트 브랜치는 강제 푸시 외엔 적용 해주지 않을거에요.
많은 분들이 머지 워크플로우를 리베이스 워크플로우보다 선호하는 많이 이유 중 하나죠 - 큰 팀에선 개발자의 강제 푸시로 곤란해질 수 있어요.
주의해서 쓰세요.
리베이스를 그나마 안전하게 쓰는 방법은 리모트 브랜치의 모든 변경점과 똑같이 반영하는게 아니라 대신에 이렇게 해봐요:
리베이스를 그나마 안전하게 쓰는 방법은 리모트 브랜치의 모든 변경점과 똑같이 반영하는게 아니라 대신에 이렇게 해봐요:
```sh
(master)$ git checkout my-branch
(my-branch)$ git rebase -i master
(my-branch)$ git checkout master
(master)$ git merge --ff-only my-branch
(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch
```
더 확인이 필요하다면, [이 스택오버플로우의 쓰레드](https://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push)를 참고해요.
@ -941,26 +941,26 @@ origin/HEAD set to master
<a name="interactive-rebase"></a>
### 커밋끼리 합치고 싶어
`master`에 풀 리퀘스트가 될 브랜치에서 작업하고 있다고 가정해봐요.
`main`에 풀 리퀘스트가 될 브랜치에서 작업하고 있다고 가정해봐요.
가장 간단한 경우는 원하는게 *모든* 커밋을 하나의 커밋으로 합치고 변경점의 시간을 신경쓰지 않아도 되는 것일 때, 리셋하고 커밋 다시하면 돼요.
마스터 브랜치가 최신이고 모든 변경점이 커밋된 것만 확인한 다음:
```sh
(my-branch)$ git reset --soft master
(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"
```
좀더 조정하고, 시간기록까지 보관하고 싶다면, 대화형 리베이스가 필요할거에요.
```sh
(my-branch)$ git rebase -i master
(my-branch)$ git rebase -i main
```
만약 다른 브랜치로 붙는 작업을 하는게 아니라면, `HEAD`을 기준으로 리베이스 해야해요.
예로 마지막 2개의 커밋을 스쿼시(기존 커밋에 반영해넣는)하고 싶다면 `HEAD~2`로 리베이스 해요. 3개라면 `HEAD~3`으로 하구요.
```sh
(master)$ git rebase -i HEAD~2
(main)$ git rebase -i HEAD~2
```
대화형 리베이스를 실행하면 텍스트 에디터로 이런 것들을 볼 수 있을거에요.
@ -990,11 +990,11 @@ pick e3851e8 another fix
# Note that empty commits are commented out
```
모든 `#`으로 시작하는 주석줄은 리베이스에 영향을 주진 않아요.
모든 `#`으로 시작하는 주석줄은 리베이스에 영향을 주진 않아요.
다음으로 `pick` 부분을 다른 명령어로 바꾸거나, 해당하는 라인을 지워서 커밋을 지울 수도 있어요.
예를 들자면 **오래된 (첫번째) 커밋만 두고 두번째 오래된 커밋과 나머지를 다 합치고 싶을때**, 첫번째와 두번째 커밋 제외한 나머지 커맨드들을 `f`로 바꿔야 할거에요:
예를 들자면 **오래된 (첫번째) 커밋만 두고 두번째 오래된 커밋과 나머지를 다 합치고 싶을때**, 첫번째와 두번째 커밋 제외한 나머지 커맨드들을 `f`로 바꿔야 할거에요:
```vim
pick a9c8a1d Some refactoring
@ -1020,7 +1020,7 @@ Newer, awesomer features
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
# modified: README.md
@ -1030,7 +1030,7 @@ Newer, awesomer features
전부 다 성공하면, 이런 메세지를 볼거에요:
```sh
(master)$ Successfully rebased and updated refs/heads/master.
(main)$ Successfully rebased and updated refs/heads/main.
```
#### 안전한 머지 전략
@ -1040,13 +1040,13 @@ Newer, awesomer features
```sh
(master)$ git merge --no-ff --no-commit my-branch
(main)$ git merge --no-ff --no-commit my-branch
```
#### 브랜치를 커밋 하나로 머지해야해
#### 브랜치를 커밋 하나로 머지해야해
```sh
(master)$ git merge --squash my-branch
(main)$ git merge --squash my-branch
```
<a name="rebase-unpushed-commits"></a>
@ -1056,10 +1056,10 @@ Newer, awesomer features
다른 누군가가 벌써 참고해서 커밋을 만들고 있을테니 이미 푸시된 커밋을 잘못 합치길 바라진 않을거에요.
```sh
(master)$ git rebase -i @{u}
(main)$ git rebase -i @{u}
```
이 명령은 아직 푸시하지 않은 커밋만으로 대화형 리베이스를 실행해요. 그러니 목록 내에 있는 어떤 커밋이든 재정렬/수정/합치기 안전해요.
이 명령은 아직 푸시하지 않은 커밋만으로 대화형 리베이스를 실행해요. 그러니 목록 내에 있는 어떤 커밋이든 재정렬/수정/합치기 안전해요.
#### 머지를 중단해야해
@ -1076,13 +1076,13 @@ Newer, awesomer features
브랜치 내 모든 커밋이 다른 브랜치로 머지됐는지 확인하려면, 그 브랜치들 HEAD (또는 특정 커밋)를 비교해야해요:
```sh
(master)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
```
이 명령은 어디에는 있고 다른덴 없는 커밋이 있나를 알려줄거에요 그리고 브랜치들 사이에 공유되지 않은게 목록을 보여줄 거구요. 다른 옵션은 이렇게:
```sh
(master)$ git log master ^feature/120-on-scroll --no-merges
(main)$ git log main ^feature/120-on-scroll --no-merges
```
### 대화형 리베이스로 발생가능한 이슈
@ -1107,7 +1107,7 @@ noop
리베이스를 똑바로 끝내지 못했다면, 충돌을 해결해야 할거에요.
어떤 파일이 충돌났는지 `git status`를 먼저 실행해봐요:
어떤 파일이 충돌났는지 `git status`를 먼저 실행해봐요:
```sh
(my-branch)$ git status
@ -1134,16 +1134,16 @@ Changes not staged for commit:
어느 한쪽 브랜치의 코드를 남기고 싶다면, `--ours` 또는 `--theirs`를 쓰면 돼요:
```sh
(master*)$ git checkout --ours README.md
(main*)$ git checkout --ours README.md
```
- *머지*할때, `--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#git-rebase---merge)를 보세요.
만약 머지가 더 복잡하면, 비주얼 디프 에디터를 쓸 수도 있어요:
```sh
(master*)$ git mergetool -t opendiff
(main*)$ git mergetool -t opendiff
```
코드의 충돌을 해결하고 테스트가 해결되고 나면, 바뀐 파일 내용을 `git add` 해주고, `git rebase --continue`로 리베이스를 이어서 해요.
@ -1155,7 +1155,7 @@ Changes not staged for commit:
만약 모든 충돌을 개선한 내용이 커밋 전과 동일한 트리 구조를 가진다면, 대신에 `git rebase --skip`를 해야 해요.
리베이스 중 멈추고 싶은 어떤 시점이거나 원래 상태의 브랜치로 돌아가고 싶다면, 이렇게 할 수 있어요:
리베이스 중 멈추고 싶은 어떤 시점이거나 원래 상태의 브랜치로 돌아가고 싶다면, 이렇게 할 수 있어요:
```sh
(my-branch)$ git rebase --abort
@ -1200,7 +1200,7 @@ $ git stash save <message>
```
<a name="stash-apply-specific"></a>
### 특정 스테이시 목록에서 가져와 적용하기
### 특정 스테이시 목록에서 가져와 적용하기
메세지 작성된 스테이시 리스트 먼저 확인하세요
@ -1263,7 +1263,7 @@ $ git log -- <path to file>
$ git log -- **/*.js
```
와일드 카드를 쓸 때, 커밋된 파일의 목록을 볼 수 있는 `--name-status`로 확인하는게 유용할거에요:
와일드 카드를 쓸 때, 커밋된 파일의 목록을 볼 수 있는 `--name-status`로 확인하는게 유용할거에요:
```sh
$ git log --name-status -- **/*.js
@ -1315,7 +1315,7 @@ $ rm -rf .git/modules/submodulename
$ git rev-list -n 1 HEAD -- filename
```
그런 다음 그 파일을 체크아웃해요
그런 다음 그 파일을 체크아웃해요
```
git checkout deletingcommitid^ -- filename
@ -1362,7 +1362,7 @@ From github.com:foo/bar
### Zip파일로 레파지토리 추출하기
```sh
$ git archive --format zip --output /full/path/to/zipfile.zip master
$ git archive --format zip --output /full/path/to/zipfile.zip main
```
## 파일 추적하기
@ -1372,21 +1372,21 @@ $ git archive --format zip --output /full/path/to/zipfile.zip master
### 파일 내용엔 변경이 없이 파일 이름을 앞글자만 대문자로 바꾸고 싶어
```sh
(master)$ git mv --force myfile MyFile
(main)$ git mv --force myfile MyFile
```
### 깃 풀 받을때 로컬 파일을 덮어씌우고 싶어
```sh
(master)$ git fetch --all
(master)$ git reset --hard origin/master
(main)$ git fetch --all
(main)$ git reset --hard origin/main
```
<a href="remove-from-git"></a>
### 파일을 로컬에는 보관하고 깃에서 지우고 싶어
```sh
(master)$ git rm --cached log.txt
(main)$ git rm --cached log.txt
```
### 특정한 버전대로 파일을 복구하고 싶어
@ -1394,13 +1394,13 @@ $ git archive --format zip --output /full/path/to/zipfile.zip master
복구하고 싶은 해시가 c5f567 이라고 가정하면:
```sh
(master)$ git checkout c5f567 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567 -- file1/to/restore file2/to/restore
```
c5f567 한 단계전으로 복구하고 싶다면, c5f567~1로 적어줘요:
```sh
(master)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
```
### 커밋과 브랜치 간의 특정 파일 변경 이력이 필요해
@ -1415,14 +1415,14 @@ $ git diff HEAD:path_to_file/file c5f567:path_to_file/file
브랜치도 같은 방법으로:
```sh
$ git diff master:path_to_file/file staging:path_to_file/file
$ git diff main:path_to_file/file staging:path_to_file/file
```
## 설정
### 깃 명령어 몇 개를 앨리어스 등록하고 싶어
맥OS나 리눅스에는, 깃 설정 파일이 ```~/.gitconfig``` 에 있어요. 단축용으로 (몇개는 평소 쓰는 용도로) 앨리어스 몇개를 아래와 같이 계속 추가해오고 있어요.
맥OS나 리눅스에는, 깃 설정 파일이 ```~/.gitconfig``` 에 있어요. 단축용으로 (몇개는 평소 쓰는 용도로) 앨리어스 몇개를 아래와 같이 계속 추가해오고 있어요.
```vim
[alias]
@ -1449,7 +1449,7 @@ $ git diff master:path_to_file/file staging:path_to_file/file
### 레파지토리에 빈 디렉토리를 추가하고 싶어
못해요! 깃은 지원하지 않거든요, 근데 꼼수가 있어요. 디렉토리에에 .gitignore 파일을 아래 내용으로 만들어요:
못해요! 깃은 지원하지 않거든요, 근데 꼼수가 있어요. 디렉토리에에 .gitignore 파일을 아래 내용으로 만들어요:
```
# Ignore everything in this directory
@ -1483,13 +1483,13 @@ $ git config --global credential.helper 'cache --timeout=3600'
# Set the cache to timeout after 1 hour (setting is in seconds)
```
### 깃이 권한과 파일모드 변경을 무시하게 만들고 싶어
### 깃이 권한과 파일모드 변경을 무시하게 만들고 싶어
```sh
$ git config core.fileMode false
```
이 것을 로그인된 유저의 기본 행위로 설정으로 해두려면, 이렇게 써요:
이 것을 로그인된 유저의 기본 행위로 설정으로 해두려면, 이렇게 써요:
```sh
$ git config --global core.fileMode false
@ -1497,7 +1497,7 @@ $ git config --global core.fileMode false
### 글로벌 유저로 설정해두고 싶어
모든 로컬 레파지토리에 사용되는 유저 정보를 설정하려면, 그리고 버전 이력을 리뷰할때 알아보기 쉬운 이름으로 설정하려면:
모든 로컬 레파지토리에 사용되는 유저 정보를 설정하려면, 그리고 버전 이력을 리뷰할때 알아보기 쉬운 이름으로 설정하려면:
```sh
$ git config --global user.name “[firstname lastname]”
@ -1521,14 +1521,14 @@ $ git config --global color.ui auto
음, 망했군요. 뭔가를 `reset` 했거나, 다른 브랜치로 머지했거나, 지금은 찾질 못하는 커밋으로 강제 푸시를 해버렸군요.
알다시피, 어떤 시점에선, 잘 하고 있었고 거기로 돌아가고 싶겠죠.
이게 바로 `git reflog`의 존재이유에요. `reflog` 는 브랜치 끝의 어떤 변경점이든 브랜치나 태그에 의해 참조되지 않더라도 다 보관해요.
이게 바로 `git reflog`의 존재이유에요. `reflog` 는 브랜치 끝의 어떤 변경점이든 브랜치나 태그에 의해 참조되지 않더라도 다 보관해요.
기본적으로, HEAD가 변경되는 모든 경우, 리플로그에 새로운 입력이 추가돼요. 아쉽게도 이 기능은 로컬 레파지토리에서만 동작해고, 오직 움직임만을 트래킹해요 (예를 들자면 어디에도 기록되지 않았던 파일의 변경은 아니에요)
```sh
(master)$ git reflog
(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
```
이 리플로그는 마스터에서 2.2 브랜치로 체크아웃하고 되돌린 것을 보여주네요.
@ -1542,7 +1542,7 @@ $ git reset --hard 0254ea7
```
`git reset`을 쓰는 것으로 마스터를 이전 커밋으로 되돌릴 수 있어요.
이력이 실수로 변경됐을 때의 안정망을 제공할거에요.
이력이 실수로 변경됐을 때의 안정망을 제공할거에요.
([여기](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)에서 복제해와 수정했어요).
@ -1581,7 +1581,7 @@ $ git reset --hard 0254ea7
* [Sourcetree](https://www.sourcetreeapp.com/) - 아름답고 무료인 깃 GUI 안에서 단순함과 강력함이 만났어 Windows and Mac
* [Tower](https://www.git-tower.com/) - 그래픽 Git 클라이언트 OS X (유료)
* [tig](https://jonas.github.io/tig/) - 깃을 위한 터민러 텍스트 모드 인터페이스
* [Magit](https://magit.vc/) - Emacs 패키지를 위해 구현된 깃 인터페이스
* [Magit](https://magit.vc/) - Emacs 패키지를 위해 구현된 깃 인터페이스
* [GitExtensions](https://github.com/gitextensions/gitextensions) - 쉘 확장, 비주얼 스투디오 2010-2015 플러그인 그리고 독자적인 깃 레파지토리 도구
* [Fork](https://git-fork.com/) - 빠르고 친숙한 깃 클라이언트 Mac (베타)
* [gmaster](https://gmaster.io/) - 3-way 머지, 리팩터 분석기, 시멘틱 diff와 머지 기능의 윈도 전용 깃 클라이언트 (베타)

View File

@ -67,7 +67,7 @@
- [Создать ветку на определенном коммите](#%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D1%8C-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-%D0%BD%D0%B0-%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%BC-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%B5)
- [Я стянул изменения (pull) из неправильной ветки или в неправильную ветку](#%D0%AF-%D1%81%D1%82%D1%8F%D0%BD%D1%83%D0%BB-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-pull-%D0%B8%D0%B7-%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B8-%D0%B8%D0%BB%D0%B8-%D0%B2-%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D1%83%D1%8E-%D0%B2%D0%B5%D1%82%D0%BA%D1%83)
- [Я хочу отменить локальные коммиты, чтобы моя ветка стала такой же как на сервере](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BE%D1%82%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C-%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D1%8B-%D1%87%D1%82%D0%BE%D0%B1%D1%8B-%D0%BC%D0%BE%D1%8F-%D0%B2%D0%B5%D1%82%D0%BA%D0%B0-%D1%81%D1%82%D0%B0%D0%BB%D0%B0-%D1%82%D0%B0%D0%BA%D0%BE%D0%B9-%D0%B6%D0%B5-%D0%BA%D0%B0%D0%BA-%D0%BD%D0%B0-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B5)
- [Я сохранил коммит в ветку master вместо новой ветки](#%D0%AF-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82-%D0%B2-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-master-%D0%B2%D0%BC%D0%B5%D1%81%D1%82%D0%BE-%D0%BD%D0%BE%D0%B2%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B8)
- [Я сохранил коммит в ветку main вместо новой ветки](#%D0%AF-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82-%D0%B2-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-main-%D0%B2%D0%BC%D0%B5%D1%81%D1%82%D0%BE-%D0%BD%D0%BE%D0%B2%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B8)
- [Я хочу сохранить файл целиком из другого ref-ish](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D1%82%D1%8C-%D1%84%D0%B0%D0%B9%D0%BB-%D1%86%D0%B5%D0%BB%D0%B8%D0%BA%D0%BE%D0%BC-%D0%B8%D0%B7-%D0%B4%D1%80%D1%83%D0%B3%D0%BE%D0%B3%D0%BE-ref-ish)
- [Я сделал несколько коммитов в одной ветке, а нужно было сохранять их в разных ветках](#%D0%AF-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-%D0%BD%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2-%D0%B2-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B5-%D0%B0-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE-%D0%B1%D1%8B%D0%BB%D0%BE-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D1%8F%D1%82%D1%8C-%D0%B8%D1%85-%D0%B2-%D1%80%D0%B0%D0%B7%D0%BD%D1%8B%D1%85-%D0%B2%D0%B5%D1%82%D0%BA%D0%B0%D1%85)
- [Я хочу удалить локальные ветки, которые были удалены в upstream](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%83%D0%B4%D0%B0%D0%BB%D0%B8%D1%82%D1%8C-%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%B2%D0%B5%D1%82%D0%BA%D0%B8-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B5-%D0%B1%D1%8B%D0%BB%D0%B8-%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D1%8B-%D0%B2-upstream)
@ -240,18 +240,18 @@ Git не располагает командами для создания пу
Возможно, вы уже настроили ссылку на исходный удаленный репозиторий. Если нет, тогда сделайте это сейчас. Обычно исходный удаленный репозиторий называют `upstream`:
```sh
$ (master) git remote add upstream <link-to-original-repository>
# $ (master) git remote add upstream git@github.com:k88hudson/git-flight-rules.git
$ (main) git remote add upstream <link-to-original-repository>
# $ (main) git remote add upstream git@github.com:k88hudson/git-flight-rules.git
```
Теперь вы можете получить последние обновления из upstream.
```sh
$ (master) git fetch upstream
$ (master) git merge upstream/master
$ (main) git fetch upstream
$ (main) git merge upstream/main
# или одной командой
$ (master) git pull upstream master
$ (main) git pull upstream main
```
## Редактирование коммитов
@ -262,7 +262,7 @@ $ (master) git pull upstream master
Допустим, Вы не глядя сохранили изменения с помощью `git commit -a` и теперь не уверены что именно сохранили. В таком случае Вы можете просмотреть последний коммит в HEAD с помощью:
```sh
(master)$ git show
(main)$ git show
```
Или
@ -391,13 +391,13 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Замечание: Это относится только если ваша работа была сохранена, т.е. Вы сделали коммит или stash. `git reset --hard` *удалит* несохраненные изменения, так что пользуйтесь им с осторожностью. (Безопасная опция это `git reset --keep`.)
```sh
(master)$ git reflog
(main)$ git reflog
```
Вы увидете список Ваших предыдущих коммитов и коммит для сброса. Выберите SHA коммита, который хотите вернуть и снова сделайте сброс:
```sh
(master)$ git reset --hard SHA1234
(main)$ git reset --hard SHA1234
```
И Вы сможете продолжить работу.
@ -405,7 +405,7 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
<a href="undo-a-commit-merge"></a>
### Я случайно опубликовал ненужное слияние
Если Вы случайно сделали слияние в основную ветку разработки до того, как были сделаны все необходимые изменения, Вы по-прежнему можете отменить слияние. Но есть одна загвоздка: Коммит слияния имеет более одного родителя (обычно два).
Если Вы случайно сделали слияние в основную ветку разработки до того, как были сделаны все необходимые изменения, Вы по-прежнему можете отменить слияние. Но есть одна загвоздка: Коммит слияния имеет более одного родителя (обычно два).
Команда для решения этой проблемы
```sh
@ -463,17 +463,17 @@ echo sensitive_file >> .gitignore
Чтобы удалить определенный файл:
```sh
(master)$ git rm path/to/filetoremove
(master)$ git commit -m "Commit removing filetoremove"
(master)$ java -jar ~/Downloads/bfg.jar --delete-files filetoremove
(main)$ git rm path/to/filetoremove
(main)$ git commit -m "Commit removing filetoremove"
(main)$ java -jar ~/Downloads/bfg.jar --delete-files filetoremove
```
Заметьте, что в bfg вы должны использовать имя файла без пути, даже если файл находится в подкаталоге.
Также вы можете пользоваться шаблонами имен:
```sh
(master)$ git rm *.jpg
(master)$ git commit -m "Commit removing *.jpg"
(master)$ java -jar ~/Downloads/bfg.jar --delete-files *.jpg
(main)$ git rm *.jpg
(main)$ git commit -m "Commit removing *.jpg"
(main)$ java -jar ~/Downloads/bfg.jar --delete-files *.jpg
```
При использовании bfg, файлы, существующие в вашем последнем коммите не будут затронуты. Например, если в вашем репозитории было много больших .tga файлов, а потом вы удалили несколько из них, то bfg не тронет файлы, которые присутствуют в последнем коммите.
@ -487,7 +487,7 @@ echo sensitive_file >> .gitignore
В приведенной ниже команде замените `filepattern` на требуемое имя или шаблон, например, `*.jpg`. Эта команда удалит файлы, подходящие под заданный шаблон из истории всех ветвей.
```sh
(master)$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch filepattern' --prune-empty --tag-name-filter cat -- --all
(main)$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch filepattern' --prune-empty --tag-name-filter cat -- --all
```
Пояснения:
@ -501,19 +501,19 @@ echo sensitive_file >> .gitignore
Как только вы удалили файлы, которые хотели, внимально проверьте, что ничего не сломали в репозитории - если сломали, то проще всего склонировать ваш репозиторий и начать снова.
Для завершения вы можете опционально запустить сборщик мусора Git, чтобы минимизировать размер локальной папки .git folder size, а после этого сделать принудительный push.
```sh
(master)$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
(master)$ git push origin --force --tags
(main)$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
(main)$ git push origin --force --tags
```
После того, как вы переписали всю историю репозитория, операция `git push` может оказаться слишком большой и вернет ошибку `“The remote end hung up unexpectedly” (Удаленный хост неожиданно прервал соединение)`. Если это произошло, то попробуйте увеличить размер буфера передачи:
```sh
(master)$ git config http.postBuffer 524288000
(master)$ git push --force
(main)$ git config http.postBuffer 524288000
(main)$ git push --force
```
Если это не работает, то вам придется делать push частями. В команде ниже пробуйте увеличивать `<number>` пока push не сработает.
```sh
(master)$ git push -u origin HEAD~<number>:refs/head/master --force
(main)$ git push -u origin HEAD~<number>:refs/head/main --force
```
После того как только команда push сработала в первый раз, постепенно уменьшайте `<number>`, пока не сработает обычная `git push`.
@ -640,7 +640,7 @@ $ git stash pop
```sh
(my-branch)$ git reset --hard
# or
(master)$ git checkout -f
(main)$ git checkout -f
```
Это уберет из индекса все подготовленные изменения:
@ -778,7 +778,7 @@ $ git checkout -b <branch> <SHA1_OF_COMMIT>
Это очередная возможность воспользоваться `git reflog`, чтобы посмотреть куда указывала ваша HEAD перед неправильным pull.
```sh
(master)$ git reflog
(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here
```
@ -809,22 +809,22 @@ $ git reset --hard c5bc55a
Один из способов сбросить до источника (чтобы иметь то же, что и в удаленном репозитории):
```sh
(master)$ git reset --hard origin/my-branch
(main)$ git reset --hard origin/my-branch
```
<a name="commit-wrong-branch"></a>
### Я сохранил коммит в ветку master вместо новой ветки
### Я сохранил коммит в ветку main вместо новой ветки
Создайте новую ветку, оставаясь на master:
Создайте новую ветку, оставаясь на main:
```sh
(master)$ git branch my-branch
(main)$ git branch my-branch
```
Сбросьте ветку master к предыдущему коммиту:
Сбросьте ветку main к предыдущему коммиту:
```sh
(master)$ git reset --hard HEAD^
(main)$ git reset --hard HEAD^
```
`HEAD^` - это сокращение для `HEAD^1`. Это подставляет первого предка `HEAD`, подобно этому `HEAD^2` подставляет второго предка коммита (слияния могут иметь 2 предков).
@ -833,17 +833,17 @@ $ git reset --hard c5bc55a
Если не хотите использовать `HEAD^`, то найдите хэш коммита, на который Вы хотите установить ветку (`git log` может помочь в этом). Затем сделайте сброс к этому хэшу. С помощью `git push` удостоверьтесь, что эти изменения отражены в удаленном репозитории.
К примеру, ветка master обязана находится на коммите с хэшем `a13b85e`:
К примеру, ветка main обязана находится на коммите с хэшем `a13b85e`:
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Перейти на новую ветку для продолжения работы:
```sh
(master)$ git checkout my-branch
(main)$ git checkout my-branch
```
<a name="keep-whole-file"></a>
@ -886,10 +886,10 @@ HEAD is now at a13b85e
<a name="cherry-pick"></a>
### Я сделал несколько коммитов в одной ветке, а нужно было сохранять их в разных ветках
Скажем, Вы в ветке master. Запустив `git log`, Вы увидите, что сделали два коммита:
Скажем, Вы в ветке main. Запустив `git log`, Вы увидите, что сделали два коммита:
```sh
(master)$ git log
(main)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
@ -912,17 +912,17 @@ Date: Tue Jul 21 01:12:48 2014 -0400
Обратим внимание на ссылки на каждый баг (`e3851e8` для #21, `5ea5173` для #14).
Во-первых, сбросим ветку master на правильный коммит (`a13b85e`):
Во-первых, сбросим ветку main на правильный коммит (`a13b85e`):
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Теперь, мы может создать новую ветку для бага #21:
```sh
(master)$ git checkout -b 21
(main)$ git checkout -b 21
(21)$
```
@ -934,11 +934,11 @@ HEAD is now at a13b85e
На этом этапе есть вероятность конфликтов. О том как разрешить конфликты см. в главе [**Здесь были конфликты**](#merge-conflict) в [разделе интерактивное перебазирование выше](#interactive-rebase).
Теперь давайте создадим новую ветку для бага #14, которая также основана на master
Теперь давайте создадим новую ветку для бага #14, которая также основана на main
```sh
(21)$ git checkout master
(master)$ git checkout -b 14
(21)$ git checkout main
(main)$ git checkout -b 14
(14)$
```
@ -964,7 +964,7 @@ $ git fetch -p upstream
Если Вы регулярно отправляете изменения в удаленное хранилище, большую часть времени Вы в безопасности. Но в один прекрасный момент Вы всё же можете случайно удалить Ваши ветки. Скажем, мы создали ветку и создали новый файл:
```sh
(master)$ git checkout -b my-branch
(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
@ -994,31 +994,31 @@ Date: Tue Jul 29 13:14:46 2014 -0400
Fixes #6: Force pushing after amending commits
```
Теперь мы переключаемся обратно на master и 'нечаянно' удаляем нашу ветку.
Теперь мы переключаемся обратно на main и 'нечаянно' удаляем нашу ветку.
```sh
(my-branch)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
(my-branch)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(master)$ echo О, нет, моя ветка удалена!
(main)$ echo О, нет, моя ветка удалена!
О, нет, моя ветка удалена!
```
На этом этапе Вы должны быть знакомы с 'reflog' (расширенный журнал). Он хранит историю всех действий в репозитории.
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to master
(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to main
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from master to my-branch
69204cd HEAD@{2}: checkout: moving from main to my-branch
```
Как мы можем видеть, у нас есть хэш коммита из удаленной ветки. Посмотрим, можем ли мы восстановить удаленную ветку.
```sh
(master)$ git checkout -b my-branch-help
(main)$ git checkout -b my-branch-help
Switched to a new branch 'my-branch-help'
(my-branch-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 foo.txt added
@ -1033,25 +1033,25 @@ README.md foo.txt
Чтобы удалить ветку на удаленном репозитории:
```sh
(master)$ git push origin --delete my-branch
(main)$ git push origin --delete my-branch
```
Вы также можете сделать:
```sh
(master)$ git push origin :my-branch
(main)$ git push origin :my-branch
```
Чтобы удалить локальную ветку:
```sh
(master)$ git branch -d my-branch
(main)$ git branch -d my-branch
```
Чтобы удалить локальную ветку, которая *не была* слита с отслеживаемой веткой (заданной с помощью `--track` или `--set-upstream`) или с HEAD:
```sh
(master)$ git branch -D my-branch
(main)$ git branch -D my-branch
```
### Я хочу удалить несколько веток
@ -1059,7 +1059,7 @@ README.md foo.txt
Скажем, Вы хотите удалить все ветки, начинающиеся с `fix/`:
```sh
(master)$ git branch | grep 'fix/' | xargs git branch -d
(main)$ git branch | grep 'fix/' | xargs git branch -d
```
### Я хочу переименовать ветку
@ -1067,13 +1067,13 @@ README.md foo.txt
Чтобы переименовать текущую (локальную) ветку:
```sh
(master)$ git branch -m new-name
(main)$ git branch -m new-name
```
Чтобы переименовать другую (локальную) ветку:
```sh
(master)$ 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>
@ -1082,13 +1082,13 @@ README.md foo.txt
Во-первых, получим все ветки из удаленного репозитория:
```sh
(master)$ git fetch --all
(main)$ git fetch --all
```
Скажем, Вы хотите перейти на `daves` из удаленного репозитория.
```sh
(master)$ git checkout --track origin/daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
```
@ -1141,14 +1141,14 @@ $ git branch -u [remotename]/[branch] [local-branch]
```sh
$ git branch -r
origin/HEAD -> origin/gh-pages
origin/master
origin/main
```
Чтобы `origin/HEAD` отслеживала `origin/master`, выполните команду:
Чтобы `origin/HEAD` отслеживала `origin/main`, выполните команду:
```sh
$ git remote set-head origin --auto
origin/HEAD set to master
origin/HEAD set to main
```
### Я сделал изменения в неправильной ветке
@ -1178,10 +1178,10 @@ origin/HEAD set to master
К сожалению, вы должны сделать принудительный push, если хотите, чтобы изменения были отражены на удаленной ветке. Это потому что у вас изменена история. Удаленная ветка не примет изменения, если не сделать принудительный push. Это одна из основных причин, по которым большинство людей основывает свой рабочий процесс на слиянии вместо перебазирования - большие команды могут столкнуться с проблемами, если разработчики будут делать принудительный `push`. Используйте это с осторожностью. Безопасный способ использовать перебазирование - это не отражать Ваши изменения напрямую на удаленную ветку, а вместо этого делать следующее:
```sh
(master)$ git checkout my-branch
(my-branch)$ git rebase -i master
(my-branch)$ git checkout master
(master)$ git merge --ff-only my-branch
(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch
```
Чтобы узнать больше, см. [эту SO ветку](https://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push).
@ -1189,23 +1189,23 @@ origin/HEAD set to master
<a name="interactive-rebase"></a>
### Я хочу объединить коммиты
Предположим, что Вы работаете в ветке, которая стала или станет пулл-реквестом в `master`. В простейшем случае когда всё, что Вы хотите сделать - это объединить *все* коммиты в один единственный коммит и Вам не важны временные метки, Вы можете сделать сброс и заново сделать коммит. Убедитесь, что ветка master обновлена и Ваши изменения сохранены, затем:
Предположим, что Вы работаете в ветке, которая стала или станет пулл-реквестом в `main`. В простейшем случае когда всё, что Вы хотите сделать - это объединить *все* коммиты в один единственный коммит и Вам не важны временные метки, Вы можете сделать сброс и заново сделать коммит. Убедитесь, что ветка main обновлена и Ваши изменения сохранены, затем:
```sh
(my-branch)$ git reset --soft master
(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"
```
Если Вы хотите больше контроля, а также сохранить метки времени, Вам нужно сделать кое-что, называемое интерактивным перебазированием:
```sh
(my-branch)$ git rebase -i master
(my-branch)$ git rebase -i main
```
Если Вы не работаете с другой веткой, можете делать перебазирование относительно Вашей `HEAD`. Например, если Вы хотите объединить последние два коммита, Вам нужно делать перебазирование относительно `HEAD~2`. Для последних 3 - `HEAD~3` и т.д.
```sh
(master)$ git rebase -i HEAD~2
(main)$ git rebase -i HEAD~2
```
После того, как запустите интерактивное перебазирование, Вы увидите нечто подобное в Вашем текстовом редакторе:
@ -1265,7 +1265,7 @@ Newer, awesomer features
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
# modified: README.md
@ -1276,20 +1276,20 @@ Newer, awesomer features
Если всё успешно, Вы увидите что-то вроде:
```sh
(master)$ Successfully rebased and updated refs/heads/master.
(main)$ Successfully rebased and updated refs/heads/main.
```
#### Безопасная стратегия слияния
`--no-commit` производит слияние, но не делает коммит результата, давая пользователю возможность проверить и доработать результат слияния перед коммитом. `no-ff` сохраняет доказательства того, что когда-то существовала ветка feature, сохраняя цельность истории проекта.
```sh
(master)$ git merge --no-ff --no-commit my-branch
(main)$ git merge --no-ff --no-commit my-branch
```
#### Мне нужно слить ветку в единственный коммит
```sh
(master)$ git merge --squash my-branch
(main)$ git merge --squash my-branch
```
<a name="rebase-unpushed-commits"></a>
@ -1298,7 +1298,7 @@ Newer, awesomer features
Иногда у Вас бывает несколько временных коммитов, которые Вы хотите объединить перед публикацией в upstream. Вы не хотите ненароком объединить свои коммиты с уже опубликованными, потому что кто-то уже мог работать с ними.
```sh
(master)$ git rebase -i @{u}
(main)$ git rebase -i @{u}
```
Это выполнит интерактивное перебазирование со списком еще не опубликованных коммитов и Вы сможете безопасно упорядочить/исправить/объединить коммиты из списка.
@ -1315,7 +1315,7 @@ Newer, awesomer features
### Мне нужно обновить родительский коммит моей ветки
Скажем, у меня есть ветка master, ветка feature-1, выросшая из master, и ветка feature-2, выросшая из feature-1. Если я сделаю коммит в feature-1, тогда родительский коммит ветки feature-2 будет не тем, что нужно (это должна быть верхушка feature-1, поскольку мы ответвились от неё). Мы можем исправить это с помощью `git rebase --onto`.
Скажем, у меня есть ветка main, ветка feature-1, выросшая из main, и ветка feature-2, выросшая из feature-1. Если я сделаю коммит в feature-1, тогда родительский коммит ветки feature-2 будет не тем, что нужно (это должна быть верхушка feature-1, поскольку мы ответвились от неё). Мы можем исправить это с помощью `git rebase --onto`.
```sh
(feature-2)$ git rebase --onto feature-1 <первый коммит из feature-2, который Вы не хотите переносить> feature-2
@ -1328,13 +1328,13 @@ Newer, awesomer features
Для проверки того, что все коммиты ветки слиты в другую ветку, Вам нужно сравнить вершины (или любые коммиты) этих ветвей:
```sh
(master)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
```
Это расскажет Вам обо всех коммитах, которые есть в одной, но отсутствуют в другой ветке и выдаст список всех различий ветвей. Или можете сделать так:
```sh
(master)$ git log master ^feature/120-on-scroll --no-merges
(main)$ git log main ^feature/120-on-scroll --no-merges
```
### Возможные проблемы интерактивного перебазирования
@ -1349,7 +1349,7 @@ noop
Это значит, что Вы пытаетесь сделать перебазирование в ветку, которая уже имеет идентичный коммит или она *впереди* текущей ветки. Вы может попробовать:
- удостовериться что Ваша ветка master находится там, где она должна быть
- удостовериться что Ваша ветка main находится там, где она должна быть
- вместо этого перебазировать `HEAD~2` или что-то более раннее
<a name="merge-conflict"></a>
@ -1384,7 +1384,7 @@ Changes not staged for commit:
Если Вы хотите сохранить версию из какой-то одной ветки, то используйте `--ours` или `--theirs`:
```sh
(master*)$ git checkout --ours README.md
(main*)$ git checkout --ours README.md
```
- Во время *слияния* используйте `--ours` для сохранения изменений из локальной ветки или `--theirs` для сохранения изменений из другой ветки.
@ -1393,7 +1393,7 @@ Changes not staged for commit:
Если слияние более сложное, можете воспользоваться визуальным редактором различий:
```sh
(master*)$ git mergetool -t opendiff
(main*)$ git mergetool -t opendiff
```
После разрешения всех конфликтов и тестирования кода подготовьте файлы, которые Вы изменили `git add`, а затем продолжите перебазирование с помощью `git rebase --continue`
@ -1615,7 +1615,7 @@ From github.com:foo/bar
### Экспорт репозитория в Zip-файл
```sh
$ git archive --format zip --output /full/path/to/zipfile.zip master
$ git archive --format zip --output /full/path/to/zipfile.zip main
```
### Как опубликовать ветку и метку, если они имеют одинаковые имена
@ -1645,21 +1645,21 @@ $ git push origin refs/tags/<tag-name>
### Я хочу изменить регистр в имени файла, не меняя содержимое файла
```sh
(master)$ git mv --force myfile MyFile
(main)$ git mv --force myfile MyFile
```
### Я хочу переписать локальные файлы при выполнении git pull
```sh
(master)$ git fetch --all
(master)$ git reset --hard origin/master
(main)$ git fetch --all
(main)$ git reset --hard origin/main
```
<a href="remove-from-git"></a>
### Я хочу удалить файл из git, но оставить сам файл
```sh
(master)$ git rm --cached log.txt
(main)$ git rm --cached log.txt
```
### Я хочу откатить файл до заданной ревизии
@ -1667,13 +1667,13 @@ $ git push origin refs/tags/<tag-name>
Полагая, что хэш желаемого коммита c5f567:
```sh
(master)$ git checkout c5f567 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567 -- file1/to/restore file2/to/restore
```
Если вы хотите откатить файл к состоянию на 1 коммит раньше, чем c5f567, задайте хэш коммита как c5f567~1:
```sh
(master)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
```
### Я хочу получить список изменений в заданном файле из разных коммитов или веток
@ -1687,7 +1687,7 @@ $ git diff HEAD:path_to_file/file c5f567:path_to_file/file
Аналогично для веток:
```sh
$ git diff master:path_to_file/file staging:path_to_file/file
$ git diff main:path_to_file/file staging:path_to_file/file
```
### Я хочу, чтобы Git игнорировал изменения в определенном файле
@ -1708,7 +1708,7 @@ $ git update-index --no-assume-unchanged file-to-stop-ignoring
Команда [git-bisect](https://git-scm.com/docs/git-bisect) с помощью двоичного поиска находит в истории Git коммит, в котором впервые появилась ошибка.
Пусть вы находитесь на ветке `master` и хотите найти коммит, которых поломал некую функцию. Вы начинаете процедуру поиска:
Пусть вы находитесь на ветке `main` и хотите найти коммит, которых поломал некую функцию. Вы начинаете процедуру поиска:
```sh
$ git bisect start
@ -1767,7 +1767,7 @@ $ (c44abbb)$ git bisect good
wip = rebase -i @{u}
zap = fetch -p
day = log --reverse --no-merges --branches=* --date=local --since=midnight --author=\"$(git config --get user.name)\"
delete-merged-branches = "!f() { git checkout --quiet master && git branch --merged | grep --invert-match '\\*' | xargs -n 1 git branch --delete; git checkout --quiet @{-1}; }; f"
delete-merged-branches = "!f() { git checkout --quiet main && git branch --merged | grep --invert-match '\\*' | xargs -n 1 git branch --delete; git checkout --quiet @{-1}; }; f"
```
### Я хочу добавить в свой репозиторий пустую папку
@ -1870,21 +1870,21 @@ $ git config --global color.ui auto
Как раз для этого и нужен `git reflog`. `reflog` отслеживает все изменения вершины ветки, даже если на эту вершину не указывает ни единая ветвь или метка. В принципе, всякий раз при изменении HEAD, в reflog добавляется новая запись. К сожалению, это работает только с локальными репозиториями и отслеживаются только движения (а не, например, изменения файла, которые не были никуда записаны).
```sh
(master)$ git reflog
(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
```
reflog выше показывает переход с ветки master на ветку 2.2 и обратно. Затем происходит жесткий сброс на старый коммит. Самое последнее действие находится вверху с надписью `HEAD@{0}`.
reflog выше показывает переход с ветки main на ветку 2.2 и обратно. Затем происходит жесткий сброс на старый коммит. Самое последнее действие находится вверху с надписью `HEAD@{0}`.
Если Вы случайно переместитесь назад, то reflog будет содержать коммит (0254ea7), на который указывала ветка master до того, как Вы случайно выбросили 2 коммита.
Если Вы случайно переместитесь назад, то reflog будет содержать коммит (0254ea7), на который указывала ветка main до того, как Вы случайно выбросили 2 коммита.
```sh
$ git reset --hard 0254ea7
```
С помощью `git reset` можно вернуть ветку master обратно на коммит, на котором она была прежде. Это обеспечивает безопасность при случайном изменении истории.
С помощью `git reset` можно вернуть ветку main обратно на коммит, на котором она была прежде. Это обеспечивает безопасность при случайном изменении истории.
(взято из [Источник](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)).

View File

@ -57,7 +57,7 @@ Tất cả các command nên làm việc với phiên bản nhỏ nhất 2.13.0.
- [Tạo một nhánh từ một commit](#t%E1%BA%A1o-m%E1%BB%99t-nh%C3%A1nh-t%E1%BB%AB-m%E1%BB%99t-commit)
- [Tôi đã pull từ / vào sai nhánh](#t%C3%B4i-%C4%91%C3%A3-pull-t%E1%BB%AB--v%C3%A0o-sai-nh%C3%A1nh)
- [Tôi muốn loại bỏ các commit trên local đển nhánh của tôi giống như một nhánh trên server](#t%C3%B4i-mu%E1%BB%91n-lo%E1%BA%A1i-b%E1%BB%8F-c%C3%A1c-commit-tr%C3%AAn-local-%C4%91%E1%BB%83n-nh%C3%A1nh-c%E1%BB%A7a-t%C3%B4i-gi%E1%BB%91ng-nh%C6%B0-m%E1%BB%99t-nh%C3%A1nh-tr%C3%AAn-server)
- [Tôi đã commit đến master thay vì một nhánh mới](#t%C3%B4i-%C4%91%C3%A3-commit-%C4%91%E1%BA%BFn-master-thay-v%C3%AC-m%E1%BB%99t-nh%C3%A1nh-m%E1%BB%9Bi)
- [Tôi đã commit đến main thay vì một nhánh mới](#t%C3%B4i-%C4%91%C3%A3-commit-%C4%91%E1%BA%BFn-main-thay-v%C3%AC-m%E1%BB%99t-nh%C3%A1nh-m%E1%BB%9Bi)
- [Tôi muốn giữ toàn bộ file từ một ref-ish khác](#t%C3%B4i-mu%E1%BB%91n-gi%E1%BB%AF-to%C3%A0n-b%E1%BB%99-file-t%E1%BB%AB-m%E1%BB%99t-ref-ish-kh%C3%A1c)
- [Tôi đã thực hiện một số commit trên một nhánh duy nhất nó nên ở trên các nhánh khác nhau](#t%C3%B4i-%C4%91%C3%A3-th%E1%BB%B1c-hi%E1%BB%87n-m%E1%BB%99t-s%E1%BB%91-commit-tr%C3%AAn-m%E1%BB%99t-nh%C3%A1nh-duy-nh%E1%BA%A5t-n%C3%B3-n%C3%AAn-%E1%BB%9F-tr%C3%AAn-c%C3%A1c-nh%C3%A1nh-kh%C3%A1c-nhau)
- [Tôi muốn xóa các nhánh local đã bị xóa luồng phía trước](#t%C3%B4i-mu%E1%BB%91n-x%C3%B3a-c%C3%A1c-nh%C3%A1nh-local-%C4%91%C3%A3-b%E1%BB%8B-x%C3%B3a-lu%E1%BB%93ng-ph%C3%ADa-tr%C6%B0%E1%BB%9Bc)
@ -160,7 +160,7 @@ $ git clone [url] name-of-new-folder
Giả sử bạn vừa commit thay đổi một cách mù quáng với lệnh `git commit -a` và bạn không chắc chắn nội dunng thực sự là của commit vừa thực hiện. Bạn có thể hiển thị ra commit gần nhất trên con trỏ HEAD hiện tại của bạn với lệnh:
```sh
(master)$ git show
(main)$ git show
```
Hoặc
@ -288,13 +288,13 @@ Nếu vô tình bạn thực hiện `git reset --hard`, bạn có thể vẫn nh
Chú ý: Điều này chỉ hợp lệ nếu luồng làm việc của bạn đã được sao lưu, tức là được commit hoặc được stash. `git reset --hard` _sẽ loại bỏ_ các thay đổi không được commit, vì vậy hãy sử dụng nó một cách thận trọng. (Một tuỳ chọn an toàn là `git reset --keep`.)
```sh
(master)$ git reflog
(main)$ git reflog
```
Bạn sẽ thấy danh sách các commit gần đây, và một commit cho reset. Chọn SHA của commit và muốn quay trở lại và reset lại:
```sh
(master)$ git reset --hard SHA1234
(main)$ git reset --hard SHA1234
```
Và bạn nên tốt hơn để đi tiếp.
@ -421,7 +421,7 @@ Nếu bạn muốn bỏ tất cả các thay đổi đã stage và chưa stage t
```sh
(my-branch)$ git reset --hard
# or
(master)$ git checkout -f
(main)$ git checkout -f
```
Nó sẽ unstage tất cả các file bạn đã stage với `git add`:
@ -559,7 +559,7 @@ $ git checkout -b <branch> <SHA1_OF_COMMIT>
Đây là một cơ hội khác để sử dụng `git reflog` để xem nơi con trỏ HEAD đã trỏ trước khi pull sai.
```sh
(master)$ git reflog
(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here
```
@ -590,41 +590,41 @@ Xác nhận rằng bạn chưa push các thay đổi của mình đến server.
Một cách khác để reset lại phù hợp với origin (để có các nhánh giống như trên remote) là thực hiện điều này:
```sh
(master)$ git reset --hard origin/my-branch
(main)$ git reset --hard origin/my-branch
```
<a name="commit-wrong-branch"></a>
### Tôi đã commit đến master thay vì một nhánh mới
### Tôi đã commit đến main thay vì một nhánh mới
Tạo nhánh mới trong khi giữ master:
Tạo nhánh mới trong khi giữ main:
```sh
(master)$ git branch my-branch
(main)$ git branch my-branch
```
Reset nhánh master đến commit trước đó:
Reset nhánh main đến commit trước đó:
```sh
(master)$ git reset --hard HEAD^
(main)$ git reset --hard HEAD^
```
`HEAD^` là viết tắt của `HEAD^1`. Điều này là viết tắt của parent `HEAD`, tương tự `HEAD^2` là viết tắt của parent thứ hai của commit (merge có thể có 2 parent).
Chú ý rằng `HEAD^2` **không** giống như `HEAD~2` (xem [link này](http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde) để có thêm thông tin).
Ngoài ra, nếu bạn không muốn sử dụng `HEAD^`, tìm mã hash của commit để thiết lập nhánh master của bạn (`git log` là một thủ thuật). Sau đó đặt lại mã hash. `git push` sẽ đảm bảo rằng thay đổi này được thể hiển trên remote của bạn.
Ngoài ra, nếu bạn không muốn sử dụng `HEAD^`, tìm mã hash của commit để thiết lập nhánh main của bạn (`git log` là một thủ thuật). Sau đó đặt lại mã hash. `git push` sẽ đảm bảo rằng thay đổi này được thể hiển trên remote của bạn.
Ví dụ, nếu hash của commit mà nhánh master của bạn được cho là `a13b85e`:
Ví dụ, nếu hash của commit mà nhánh main của bạn được cho là `a13b85e`:
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Checkout một nhánh mới để tiếp tục làm việc:
```sh
(master)$ git checkout my-branch
(main)$ git checkout my-branch
```
<a name="keep-whole-file"></a>
@ -667,10 +667,10 @@ Lưu ý: Các giải pháp tăng đột biến được thực hiện để phâ
<a name="cherry-pick"></a>
### Tôi đã thực hiện một số commit trên một nhánh duy nhất nó nên ở trên các nhánh khác nhau
Giả sử bạn đang ở trên nhánh master của bạn. Chạy `git log`, bạn thấy bạn đã thực hiện 2 commit:
Giả sử bạn đang ở trên nhánh main của bạn. Chạy `git log`, bạn thấy bạn đã thực hiện 2 commit:
```sh
(master)$ git log
(main)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
@ -693,17 +693,17 @@ Date: Tue Jul 21 01:12:48 2014 -0400
Hãy lưu ý các hash commit của chúng ta cho mỗi lỗi (`e3851e8` cho #21, `5ea5173` cho #14).
Trước tiên, hãy đặt lại nhánh master của chúng ta về commit chính xác (`a13b85e`):
Trước tiên, hãy đặt lại nhánh main của chúng ta về commit chính xác (`a13b85e`):
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Bây giờ, chúng ta có thể tạo ra một nhánh mới cho lỗi của chúng ta #21:
```sh
(master)$ git checkout -b 21
(main)$ git checkout -b 21
(21)$
```
@ -715,11 +715,11 @@ Bây giờ, hãy *cherry-pick* commit cho bug #21 trên dầu của nhánh. Đi
Tại thời điểm này, có khả năng có thể có xung đột. Hãy xem phần [**There were conflicts**](#merge-conflict) trong [phầnn interactive rebasing trên](#interactive-rebase) để làm thế nào giải quyết xung đột.
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 master
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 main
```sh
(21)$ git checkout master
(master)$ git checkout -b 14
(21)$ git checkout main
(main)$ git checkout -b 14
(14)$
```
@ -746,7 +746,7 @@ nơi, `upstream` là remote bạn muốn fetch từ đó.
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:
```sh
(master)$ git checkout -b my-branch
(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
@ -776,31 +776,31 @@ Date: Tue Jul 29 13:14:46 2014 -0400
Fixes #6: Force pushing after amending commits
```
Bây giờ chúng ta đang chuyển về master và 'vô tình' xóa nhánh của chúng ta
Bây giờ chúng ta đang chuyển về main và 'vô tình' xóa nhánh của chúng ta
```sh
(my-branch)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
(my-branch)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(master)$ echo oh noes, deleted my branch!
(main)$ echo oh noes, deleted my branch!
oh noes, deleted my branch!
```
Tại thời điểm này, bạn nên làm quen với 'reflog', một logger được nâng cấp. Nó lưu trữ lịch sử của tất cả các hành động trong repo.
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to master
(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to main
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from master to my-branch
69204cd HEAD@{2}: checkout: moving from main to my-branch
```
Như bạn có thể thấy chúng ta đã có commit hash từ nhánh đã xóa của chúng tôi. Hãy xem liệu chúng ta có thể khôi phục nhánh đã xóa của chúng ta hay không.
```sh
(master)$ git checkout -b my-branch-help
(main)$ git checkout -b my-branch-help
Switched to a new branch 'my-branch-help'
(my-branch-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 foo.txt added
@ -815,25 +815,25 @@ Và đấy! Chúng ta đã xoá file trước của chúng ta. `git reflog` cũn
Để xoá một nhánh remote:
```sh
(master)$ git push origin --delete my-branch
(main)$ git push origin --delete my-branch
```
Bạn cũng có thể làm :
```sh
(master)$ git push origin :my-branch
(main)$ git push origin :my-branch
```
Để xoá nhánh local:
```sh
(master)$ git branch -d my-branch
(main)$ git branch -d my-branch
```
Để xoá một nhánh local *không được* merge đến nhánh hiện tại hoặc một upstream:
```sh
(master)$ git branch -D my-branch
(main)$ git branch -D my-branch
```
### Tôi muốn xoá nhiều nhánh
@ -841,7 +841,7 @@ Bạn cũng có thể làm :
Giả sử bạn muốn xoá tất cả nhánh bắt đầu với `fix/`:
```sh
(master)$ git branch | grep 'fix/' | xargs git branch -d
(main)$ git branch | grep 'fix/' | xargs git branch -d
```
### Tôi muốn đổi tên một nhánh
@ -849,13 +849,13 @@ Giả sử bạn muốn xoá tất cả nhánh bắt đầu với `fix/`:
Để đổi tên nhánh local hiện tại:
```sh
(master)$ git branch -m new-name
(main)$ git branch -m new-name
```
Để đổi tên nhánh local khác:
```sh
(master)$ 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>
@ -864,13 +864,13 @@ Giả sử bạn muốn xoá tất cả nhánh bắt đầu với `fix/`:
Đầu tiên, fetch tất cả nhánh từ remote:
```sh
(master)$ git fetch --all
(main)$ git fetch --all
```
Giả sử bạn muốn checkout sang `daves` từ remote.
```sh
(master)$ git checkout --track origin/daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
```
@ -923,14 +923,14 @@ Bằng cách kiểm tra các nhánh remote của bạn, bạn có thể thấy r
```sh
$ git branch -r
origin/HEAD -> origin/gh-pages
origin/master
origin/main
```
Để thay đổi `origin/HEAD` để theo dõi `origin/master`, bạn có thể chạy command này:
Để thay đổi `origin/HEAD` để theo dõi `origin/main`, bạn có thể chạy command này:
```sh
$ git remote set-head origin --auto
origin/HEAD set to master
origin/HEAD set to main
```
### Tôi đã thực hiện thay đổi trên nhánh sai
@ -960,10 +960,10 @@ Bạn có thể đã merge hoặc rebase nhánh hiện tại của bạn với m
Thật không may, bạn phải bắt buộc push, nếu bạn muốn những thay đổi đó được ánh xạ trên nhánh remote. Điều này là do bạn đã thay đổi lịch sử. Nhánh remote sẽ không chấp nhận thay đổi trừ khi bạn ép buộc. Đây là một trong những lý do chính khiến nhiều người sử dụng một luồng merge, thay vì một luồng rebasing - các nhóm lớn có thể gặp rắc rối với các developer bắt buộc push. Sử dụng điều này một cách thận trọng. Một cách an toàn hơn để sử dụng rebase không phải là để ánh xạ các thay đổi của bạn trên nhánh remte, và thay vào đó thực hiện các thao tác sau:
```sh
(master)$ git checkout my-branch
(my-branch)$ git rebase -i master
(my-branch)$ git checkout master
(master)$ git merge --ff-only my-branch
(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch
```
Để biết thêm hãy xem [this SO thread](https://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push).
@ -971,23 +971,23 @@ Thật không may, bạn phải bắt buộc push, nếu bạn muốn những th
<a name="interactive-rebase"></a>
### Tôi cần kết hợp các commit
Giả sử bạn đang làm việc trong một nhánh có / sẽ trở thành một pull-request trái với `master`. Trong trường hợp đơn giản nhất khi tất cả những gì bạn muốn làm là kết hợp tất cả các commit thành một commit và bạn không quan tâm đến timestamo commit, bạn có thể đặt lại và commit lại. Đảm bảo rằng nhánh master được cập nhật và tất cả các thay đổi của bạn được commit, sau đó:
Giả sử bạn đang làm việc trong một nhánh có / sẽ trở thành một pull-request trái với `main`. Trong trường hợp đơn giản nhất khi tất cả những gì bạn muốn làm là kết hợp tất cả các commit thành một commit và bạn không quan tâm đến timestamo commit, bạn có thể đặt lại và commit lại. Đảm bảo rằng nhánh main được cập nhật và tất cả các thay đổi của bạn được commit, sau đó:
```sh
(my-branch)$ git reset --soft master
(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"
```
Nếu bạn muốn kiểm soát nhiều hơn, và cũng để bảo vệ timestamp, bạn cần phải làm một vài thứ được gọi là một interactive rebase:
```sh
(my-branch)$ git rebase -i master
(my-branch)$ git rebase -i main
```
Nếu bạn không làm việc với một nhánh khác, bạn phải rebase liên quan tới `HEAD` của bạn. Nếu bạn muốn squash 2 commit cuối, bạn sẽ phải rebase lại `HEAD~2`. Cho commit cuối 3, `HEAD~3`,...
```sh
(master)$ git rebase -i HEAD~2
(main)$ git rebase -i HEAD~2
```
Sau khi bạn chạy lệnh rebase interactive, bạn sẽ thấy một cái gì đó như thế này trong trình soạn thảo của bạn:
@ -1047,7 +1047,7 @@ Newer, awesomer features
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
# modified: README.md
@ -1058,20 +1058,20 @@ Newer, awesomer features
Nếu mọi thứ thành công, bạn sẽ thấy một cái gì đó như thế này:
```sh
(master)$ Successfully rebased and updated refs/heads/master.
(main)$ Successfully rebased and updated refs/heads/main.
```
#### Chiến lược merge an toàn
`--no-commit` thực hiện merge nhưng giả vờ hợp nhất không thành công và không tự động, cho phép người dùng có cơ hội kiểm tra và tinh chỉnh thêm kết quả merge trước khi commit. `no-ff` duy trì bằng chứng rằng một nhánh tính năng đã từng tồn tại, giữ cho lịch sử dự án nhất quán.
```sh
(master)$ git merge --no-ff --no-commit my-branch
(main)$ git merge --no-ff --no-commit my-branch
```
#### Tôi cần merge một nhánh vào một commit duy nhất
```sh
(master)$ git merge --squash my-branch
(main)$ git merge --squash my-branch
```
<a name="rebase-unpushed-commits"></a>
@ -1080,7 +1080,7 @@ Nếu mọi thứ thành công, bạn sẽ thấy một cái gì đó như thế
Đôi khi bạn có một số công việc đang tiến hành commit bạn muốn kết hợp trước khi bạn đẩy chúng lên upstream. Bạn không muốn vô tình kết hợp bất kỳ commit nào đã được push lên upstream vì một người khác có thể đã thực hiện các commit tham chiếu đến chúng.
```sh
(master)$ git rebase -i @{u}
(main)$ git rebase -i @{u}
```
Điều này sẽ làm một interactive rebase mà chỉ liệt kê các commit mà bạn chưa push, vì vậy nó sẽ được an toàn để sắp xếp lại / sửa chữa / squash bất cứ điều gì trong danh sách
@ -1097,7 +1097,7 @@ Lệnh này có sẵn kể từ phiên bản Git >= 1.7.4
### Tôi cần cập nhật commit cha của nhánh của tôi
Giả sử tôi có một nhánh master, một nhánh feature-1 tách nhánh từ master và một nhánh feature-2 tách nhánh từ feature-1. Nếu tôi thực hiện commit đối với feature-1, thì commit của feature-2 không còn chính xác nữa (nó phải là phần đầu của feature-1, vì chúng ta đã phân nhánh nó). Chúng ta có thể sửa điều này với `git rebase --onto`.
Giả sử tôi có một nhánh main, một nhánh feature-1 tách nhánh từ main và một nhánh feature-2 tách nhánh từ feature-1. Nếu tôi thực hiện commit đối với feature-1, thì commit của feature-2 không còn chính xác nữa (nó phải là phần đầu của feature-1, vì chúng ta đã phân nhánh nó). Chúng ta có thể sửa điều này với `git rebase --onto`.
```sh
(feature-2)$ git rebase --onto feature-1 <the first commit in your feature-2 branch that you don't want to bring along> feature-2
@ -1110,13 +1110,13 @@ Giả sử tôi có một nhánh master, một nhánh feature-1 tách nhánh t
Để kiểm cháu tất cả commit trên một nhánh được merge vào nhánh khác, bạn nên diff giữa các head (hoặc mọi commit) của những nhánh đó:
```sh
(master)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
```
Điều này sẽ cho bạn biết nếu bất kỳ commit trong một nhưng không phải là nhánh khác, và sẽ cung cấp cho bạn một danh sách của bất kỳ nonshared giữa các nhánh. Một lựa chọn khác là làm điều này:
```sh
(master)$ git log master ^feature/120-on-scroll --no-merges
(main)$ git log main ^feature/120-on-scroll --no-merges
```
### Các vấn đề có thể xảy ra với interactive rebases
@ -1131,7 +1131,7 @@ noop
Điều này có nghĩa bạn đang cố rebase lại một nhánh mà là một commit giống hệt nhau hoặc là *ahead* của nhánh hiện tại. Bạn có thể thử:
* đảm bảo nhánh master của bạn là nơi nó cần
* đảm bảo nhánh main của bạn là nơi nó cần
* rebase lại `HEAD~2` hoặc sớm hơn
<a name="merge-conflict"></a>
@ -1166,7 +1166,7 @@ Bạn sẽ cần phải giải quyết sự khác biệt giữa code đã đư
Nếu bạn muốn giữ phiên bản code của một nhánh, bạn có thể sử dụng `--ours` hoặc `--theirs`:
```sh
(master*)$ git checkout --ours README.md
(main*)$ git checkout --ours README.md
```
- Khi *đang merge*, sử dụng `--ours` để giữa các thay đổi từ nhánh local, hoặc `--theirs` để giữ các thay đổi từ nhánh khác.
@ -1175,7 +1175,7 @@ Nếu bạn muốn giữ phiên bản code của một nhánh, bạn có thể s
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:
```sh
(master*)$ git mergetool -t opendiff
(main*)$ git mergetool -t opendiff
```
Sau khi bạn đã giải quyết tất cả xung đột và đã kiểm tra code của mình, `git add` các file đã thay đổi và sau đó tiếp tục rebase với `git rebase --continue`
@ -1387,7 +1387,7 @@ From github.com:foo/bar
### Xuất một repository ra một file Zip
```sh
$ git archive --format zip --output /full/path/to/zipfile.zip master
$ git archive --format zip --output /full/path/to/zipfile.zip main
```
### Push một nhánh và một tag có tên giống nhau
@ -1417,21 +1417,21 @@ $ git push origin refs/tags/<tag-name>
### 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
(master)$ git mv --force myfile MyFile
(main)$ git mv --force myfile MyFile
```
### Tôi muốn ghi đè lên các tệp local khi thực hiện lệnh git pull
```sh
(master)$ git fetch --all
(master)$ git reset --hard origin/master
(main)$ git fetch --all
(main)$ git reset --hard origin/main
```
<a href="remove-from-git"></a>
### Tôi muốn xóa một tệp khỏi Git nhưng vẫn giữ tệp
```sh
(master)$ git rm --cached log.txt
(main)$ git rm --cached log.txt
```
### Tôi muốn revert tệp về bản sửa đổi cụ thể
@ -1439,13 +1439,13 @@ $ git push origin refs/tags/<tag-name>
Giả sử mã hash của commit bạn muốn c5f567:
```sh
(master)$ git checkout c5f567 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567 -- file1/to/restore file2/to/restore
```
Nếu bạn muốn revert các thay đổi được thực hiện chỉ 1 commit trước c5f567, vượt qua commit hash như c5f567~1:
```sh
(master)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
(main)$ git checkout c5f567~1 -- file1/to/restore file2/to/restore
```
### Tôi muốn liệt kê các thay đổi của một tệp cụ thể giữa các commit hoặc các nhánh
@ -1459,7 +1459,7 @@ $ git diff HEAD:path_to_file/file c5f567:path_to_file/file
Cùng đi cho các nhánh:
```sh
$ git diff master:path_to_file/file staging:path_to_file/file
$ git diff main:path_to_file/file staging:path_to_file/file
```
### Tôi muốn Git bỏ qua những thay đổi đối với một tệp cụ thể
@ -1530,7 +1530,7 @@ Bạn cũng có thể đặt tên tệp là .keep, trong trường hợp dòng t
### Tôi muốn cache một username và password cho một repository
Bạn có thể có một repository yêu cầu xác thực. Trong trường hợp này bạn có thể cache một username và password vì vậy bạn không phải nhập nó vào mỗi lần push / pull. Việc xác thực có thể làm điều này cho bạn.
Bạn có thể có một repository yêu cầu xác thực. Trong trường hợp này bạn có thể cache một username và password vì vậy bạn không phải nhập nó vào mỗi lần push / pull. Việc xác thực có thể làm điều này cho bạn.
```sh
$ git config --global credential.helper cache
@ -1582,21 +1582,21 @@ Vì vậy, bạn đang say - bạn `reset` vài thứ, hoặc bạn merge sai nh
Đây là những gì `git reflog` cho. `reflog` theo dõi bất kỳ thay đổi nào đối với mẹo của nhánh, ngay cả khi mẹo đó không được tham chiếu bởi nhánh hoặc tag. Về cơ bản, mỗi lần HEAD thay đổi, một mục mới được thêm vào reflog. Điều này chỉ hoạt động đối với các repository cục bộ, thật đáng buồn, và nó chỉ theo dõi các chuyển động (ví dụ: không thay đổi một tệp không được ghi ở bất kỳ đâu).
```sh
(master)$ git reflog
(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
```
Các reflog ở trên cho thấy một checkout từ master đến nhánh 2.2 và trở lại. Từ đó, có một thiết lập cứng để một commit cũ hơn. Hoạt động mới nhất được thể hiện ở đầu được gắn nhãn `HEAD@{0}`.
Các reflog ở trên cho thấy một checkout từ main đến nhánh 2.2 và trở lại. Từ đó, có một thiết lập cứng để một commit cũ hơn. Hoạt động mới nhất được thể hiện ở đầu được gắn nhãn `HEAD@{0}`.
Nếu nó chỉ ra rằng bạn vô tình di chuyển trở lại, các reflog sẽ chứa commit master chỉ đến (0254ea7) trước khi bạn vô tình giảm 2 commit
Nếu nó chỉ ra rằng bạn vô tình di chuyển trở lại, các reflog sẽ chứa commit main chỉ đến (0254ea7) trước khi bạn vô tình giảm 2 commit
```sh
$ git reset --hard 0254ea7
```
Sử dụng `git reset` sau đó nó có thể thay đổi master trở về commit trước đó. Điều này cung cấp sự an toàn trong trường hợp lịch sử đã vô tình thay đổi.
Sử dụng `git reset` sau đó nó có thể thay đổi main trở về commit trước đó. Điều này cung cấp sự an toàn trong trường hợp lịch sử đã vô tình thay đổi.
(đã sao chép và chỉnh sửa từ [Source](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)).

View File

@ -5,7 +5,7 @@
#### 前言
- 英文原版[README](https://github.com/k88hudson/git-flight-rules/blob/master/README.md)
- 英文原版[README](https://github.com/k88hudson/git-flight-rules/blob/main/README.md)
- 翻译可能存在错误或不标准的地方,欢迎大家指正和修改,谢谢!
#### 什么是"飞行规则"?
@ -49,7 +49,7 @@
- [分支(Branches)](#%E5%88%86%E6%94%AFbranches)
- [我从错误的分支拉取了内容,或把内容拉取到了错误的分支](#%E6%88%91%E4%BB%8E%E9%94%99%E8%AF%AF%E7%9A%84%E5%88%86%E6%94%AF%E6%8B%89%E5%8F%96%E4%BA%86%E5%86%85%E5%AE%B9%E6%88%96%E6%8A%8A%E5%86%85%E5%AE%B9%E6%8B%89%E5%8F%96%E5%88%B0%E4%BA%86%E9%94%99%E8%AF%AF%E7%9A%84%E5%88%86%E6%94%AF)
- [我想扔掉本地的提交(commit),以便我的分支与远程的保持一致](#%E6%88%91%E6%83%B3%E6%89%94%E6%8E%89%E6%9C%AC%E5%9C%B0%E7%9A%84%E6%8F%90%E4%BA%A4commit%E4%BB%A5%E4%BE%BF%E6%88%91%E7%9A%84%E5%88%86%E6%94%AF%E4%B8%8E%E8%BF%9C%E7%A8%8B%E7%9A%84%E4%BF%9D%E6%8C%81%E4%B8%80%E8%87%B4)
- [我需要提交到一个新分支但错误的提交到了master](#%E6%88%91%E9%9C%80%E8%A6%81%E6%8F%90%E4%BA%A4%E5%88%B0%E4%B8%80%E4%B8%AA%E6%96%B0%E5%88%86%E6%94%AF%E4%BD%86%E9%94%99%E8%AF%AF%E7%9A%84%E6%8F%90%E4%BA%A4%E5%88%B0%E4%BA%86master)
- [我需要提交到一个新分支但错误的提交到了main](#%E6%88%91%E9%9C%80%E8%A6%81%E6%8F%90%E4%BA%A4%E5%88%B0%E4%B8%80%E4%B8%AA%E6%96%B0%E5%88%86%E6%94%AF%E4%BD%86%E9%94%99%E8%AF%AF%E7%9A%84%E6%8F%90%E4%BA%A4%E5%88%B0%E4%BA%86main)
- [我想保留来自另外一个ref-ish的整个文件](#%E6%88%91%E6%83%B3%E4%BF%9D%E7%95%99%E6%9D%A5%E8%87%AA%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AAref-ish%E7%9A%84%E6%95%B4%E4%B8%AA%E6%96%87%E4%BB%B6)
- [我把几个提交(commit)提交到了同一个分支,而这些提交应该分布在不同的分支里](#%E6%88%91%E6%8A%8A%E5%87%A0%E4%B8%AA%E6%8F%90%E4%BA%A4commit%E6%8F%90%E4%BA%A4%E5%88%B0%E4%BA%86%E5%90%8C%E4%B8%80%E4%B8%AA%E5%88%86%E6%94%AF%E8%80%8C%E8%BF%99%E4%BA%9B%E6%8F%90%E4%BA%A4%E5%BA%94%E8%AF%A5%E5%88%86%E5%B8%83%E5%9C%A8%E4%B8%8D%E5%90%8C%E7%9A%84%E5%88%86%E6%94%AF%E9%87%8C)
- [我想删除上游(upstream)分支被删除了的本地分支](#%E6%88%91%E6%83%B3%E5%88%A0%E9%99%A4%E4%B8%8A%E6%B8%B8upstream%E5%88%86%E6%94%AF%E8%A2%AB%E5%88%A0%E9%99%A4%E4%BA%86%E7%9A%84%E6%9C%AC%E5%9C%B0%E5%88%86%E6%94%AF)
@ -101,7 +101,7 @@
如果你用 `git commit -a` 提交了一次变化(changes),而你又不确定到底这次提交了哪些内容。 你就可以用下面的命令显示当前`HEAD`上的最近一次的提交(commit):
```sh
(master)$ git show
(main)$ git show
```
或者
@ -208,13 +208,13 @@ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
如果你意外的做了 `git reset --hard`, 你通常能找回你的提交(commit), 因为Git对每件事都会有日志且都会保存几天。
```sh
(master)$ git reflog
(main)$ git reflog
```
你将会看到一个你过去提交(commit)的列表, 和一个重置的提交。 选择你想要回到的提交(commit)的SHA再重置一次:
```sh
(master)$ git reset --hard SHA1234
(main)$ git reset --hard SHA1234
```
这样就完成了。
@ -299,7 +299,7 @@ $ git stash pop
# four commits
(my-branch)$ git reset --hard HEAD~4
# or
(master)$ git checkout -f
(main)$ git checkout -f
```
重置某个特殊的文件, 你可以用文件名做为参数:
@ -345,7 +345,7 @@ $ git stash drop
这是另外一种使用 `git reflog` 情况,找到在这次错误拉(pull) 之前HEAD的指向。
```sh
(master)$ git reflog
(main)$ git reflog
ab7555f HEAD@{0}: pull origin wrong-branch: Fast-forward
c5bc55a HEAD@{1}: checkout: checkout message goes here
```
@ -376,39 +376,39 @@ $ git reset --hard c5bc55a
一种方法是:
```sh
(master)$ git reset --hard origin/my-branch
(main)$ git reset --hard origin/my-branch
```
<a name="commit-wrong-branch"></a>
### 我需要提交到一个新分支但错误的提交到了master
### 我需要提交到一个新分支但错误的提交到了main
在master下创建一个新分支不切换到新分支,仍在master下:
在main下创建一个新分支不切换到新分支,仍在main下:
```sh
(master)$ git branch my-branch
(main)$ git branch my-branch
```
把master分支重置到前一个提交:
把main分支重置到前一个提交:
```sh
(master)$ git reset --hard HEAD^
(main)$ git reset --hard HEAD^
```
`HEAD^``HEAD^1` 的简写,你可以通过指定要设置的`HEAD`来进一步重置。
或者, 如果你不想使用 `HEAD^`, 找到你想重置到的提交(commit)的hash(`git log` 能够完成) 然后重置到这个hash。 使用`git push` 同步内容到远程。
例如, master分支想重置到的提交的hash为`a13b85e`:
例如, main分支想重置到的提交的hash为`a13b85e`:
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
签出(checkout)刚才新建的分支继续工作:
```sh
(master)$ git checkout my-branch
(main)$ git checkout my-branch
```
<a name="keep-whole-file"></a>
@ -451,10 +451,10 @@ Note: Spike solutions are made to analyze or solve the problem. These solutions
<a name="cherry-pick"></a>
### 我把几个提交(commit)提交到了同一个分支,而这些提交应该分布在不同的分支里
假设你有一个`master`分支, 执行`git log`, 你看到你做过两次提交:
假设你有一个`main`分支, 执行`git log`, 你看到你做过两次提交:
```sh
(master)$ git log
(main)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
@ -477,17 +477,17 @@ Date: Tue Jul 21 01:12:48 2014 -0400
让我们用提交hash(commit hash)标记bug (`e3851e8` for #21, `5ea5173` for #14).
首先, 我们把`master`分支重置到正确的提交(`a13b85e`):
首先, 我们把`main`分支重置到正确的提交(`a13b85e`):
```sh
(master)$ git reset --hard a13b85e
(main)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
现在, 我们对 bug #21 创建一个新的分支:
```sh
(master)$ git checkout -b 21
(main)$ git checkout -b 21
(21)$
```
@ -499,11 +499,11 @@ HEAD is now at a13b85e
这时候, 这里可能会产生冲突, 参见[交互式 rebasing 章](#interactive-rebase) [**冲突节**](#merge-conflict) 解决冲突.
再者, 我们为bug #14 创建一个新的分支, 也基于`master`分支
再者, 我们为bug #14 创建一个新的分支, 也基于`main`分支
```sh
(21)$ git checkout master
(master)$ git checkout -b 14
(21)$ git checkout main
(main)$ git checkout -b 14
(14)$
```
@ -527,7 +527,7 @@ $ git fetch -p
如果你定期推送到远程, 多数情况下应该是安全的,但有些时候还是可能删除了还没有推到远程的分支。 让我们先创建一个分支和一个新的文件:
```sh
(master)$ git checkout -b my-branch
(main)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
@ -557,31 +557,31 @@ Date: Tue Jul 29 13:14:46 2014 -0400
Fixes #6: Force pushing after amending commits
```
现在我们切回到主(master)分支,‘不小心的’删除`my-branch`分支
现在我们切回到主(main)分支,‘不小心的’删除`my-branch`分支
```sh
(my-branch)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
(my-branch)$ git checkout main
Switched to branch 'main'
Your branch is up-to-date with 'origin/main'.
(main)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(master)$ echo oh noes, deleted my branch!
(main)$ echo oh noes, deleted my branch!
oh noes, deleted my branch!
```
在这时候你应该想起了`reflog`, 一个升级版的日志,它存储了仓库(repo)里面所有动作的历史。
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to master
(main)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to main
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from master to my-branch
69204cd HEAD@{2}: checkout: moving from main to my-branch
```
正如你所见我们有一个来自删除分支的提交hash(commit hash),接下来看看是否能恢复删除了的分支。
```sh
(master)$ git checkout -b my-branch-help
(main)$ git checkout -b my-branch-help
Switched to a new branch 'my-branch-help'
(my-branch-help)$ git reset --hard 4e3cd85
HEAD is now at 4e3cd85 foo.txt added
@ -597,19 +597,19 @@ README.md foo.txt
删除一个远程分支:
```sh
(master)$ git push origin --delete my-branch
(main)$ git push origin --delete my-branch
```
你也可以:
```sh
(master)$ git push origin :my-branch
(main)$ git push origin :my-branch
```
删除一个本地分支:
```sh
(master)$ 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>
@ -618,13 +618,13 @@ README.md foo.txt
首先, 从远程拉取(fetch) 所有分支:
```sh
(master)$ git fetch --all
(main)$ git fetch --all
```
假设你想要从远程的`daves`分支签出到本地的`daves`
```sh
(master)$ git checkout --track origin/daves
(main)$ git checkout --track origin/daves
Branch daves set up to track remote branch daves from origin.
Switched to a new branch 'daves'
```
@ -650,10 +650,10 @@ Switched to a new branch 'daves'
不幸的是,如果你想把这些变化(changes)反应到远程分支上,你就必须得强推(force push)。 是因你快进(Fast forward)了提交改变了Git历史, 远程分支不会接受变化(changes),除非强推(force push)。这就是许多人使用 merge 工作流, 而不是 rebasing 工作流的主要原因之一, 开发者的强推(force push)会使大的团队陷入麻烦。使用时需要注意,一种安全使用 rebase 的方法是,不要把你的变化(changes)反映到远程分支上, 而是按下面的做:
```sh
(master)$ git checkout my-branch
(my-branch)$ git rebase -i master
(my-branch)$ git checkout master
(master)$ git merge --ff-only my-branch
(main)$ git checkout my-branch
(my-branch)$ git rebase -i main
(my-branch)$ git checkout main
(main)$ git merge --ff-only my-branch
```
更多, 参见 [this SO thread](http://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push).
@ -661,23 +661,23 @@ Switched to a new branch 'daves'
<a name="interactive-rebase"></a>
### 我需要组合(combine)几个提交(commit)
假设你的工作分支将会做对于 `master` 的pull-request。 一般情况下你不关心提交(commit)的时间戳,只想组合 *所有* 提交(commit) 到一个单独的里面, 然后重置(reset)重提交(recommit)。 确保主(master)分支是最新的和你的变化都已经提交了, 然后:
假设你的工作分支将会做对于 `main` 的pull-request。 一般情况下你不关心提交(commit)的时间戳,只想组合 *所有* 提交(commit) 到一个单独的里面, 然后重置(reset)重提交(recommit)。 确保主(main)分支是最新的和你的变化都已经提交了, 然后:
```sh
(my-branch)$ git reset --soft master
(my-branch)$ git reset --soft main
(my-branch)$ git commit -am "New awesome feature"
```
如果你想要更多的控制, 想要保留时间戳, 你需要做交互式rebase (interactive rebase):
```sh
(my-branch)$ git rebase -i master
(my-branch)$ git rebase -i main
```
如果没有相对的其它分支, 你将不得不相对自己的`HEAD` 进行 rebase。 例如:你想组合最近的两次提交(commit), 你将相对于`HEAD~2` 进行rebase 组合最近3次提交(commit), 相对于`HEAD~3`, 等等。
```sh
(master)$ git rebase -i HEAD~2
(main)$ git rebase -i HEAD~2
```
在你执行了交互式 rebase的命令(interactive rebase command)后, 你将在你的编辑器里看到类似下面的内容:
@ -737,7 +737,7 @@ Newer, awesomer features
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
# You are currently editing a commit while rebasing branch 'main' on '8074d12'.
#
# Changes to be committed:
# modified: README.md
@ -748,20 +748,20 @@ Newer, awesomer features
如果成功了, 你应该看到类似下面的内容:
```sh
(master)$ Successfully rebased and updated refs/heads/master.
(main)$ Successfully rebased and updated refs/heads/main.
```
#### 安全合并(merging)策略
`--no-commit` 执行合并(merge)但不自动提交, 给用户在做提交前检查和修改的机会。 `no-ff` 会为特性分支(feature branch)的存在过留下证据, 保持项目历史一致。
```sh
(master)$ git merge --no-ff --no-commit my-branch
(main)$ git merge --no-ff --no-commit my-branch
```
#### 我需要将一个分支合并成一个提交(commit)
```sh
(master)$ git merge --squash my-branch
(main)$ git merge --squash my-branch
```
<a name="rebase-unpushed-commits"></a>
@ -770,7 +770,7 @@ Newer, awesomer features
有时候,在将数据推向上游之前,你有几个正在进行的工作提交(commit)。这时候不希望把已经推(push)过的组合进来,因为其他人可能已经有提交(commit)引用它们了。
```sh
(master)$ git rebase -i @{u}
(main)$ git rebase -i @{u}
```
这会产生一次交互式的rebase(interactive rebase), 只会列出没有推(push)的提交(commit) 在这个列表时进行reorder/fix/squash 都是安全的。
@ -781,13 +781,13 @@ Newer, awesomer features
检查一个分支上的所有提交(commit)是否都已经合并(merge)到了其它分支, 你应该在这些分支的head(或任何 commits)之间做一次diff:
```sh
(master)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
(main)$ git log --graph --left-right --cherry-pick --oneline HEAD...feature/120-on-scroll
```
这会告诉你在一个分支里有而另一个分支没有的所有提交(commit), 和分支之间不共享的提交(commit)的列表。 另一个做法可以是:
```sh
(master)$ git log master ^feature/120-on-scroll --no-merges
(main)$ git log main ^feature/120-on-scroll --no-merges
```
### 交互式rebase(interactive rebase)可能出现的问题
@ -802,7 +802,7 @@ noop
这意味着你rebase的分支和当前分支在同一个提交(commit)上, 或者 *领先(ahead)* 当前分支。 你可以尝试:
* 检查确保主(master)分支没有问题
* 检查确保主(main)分支没有问题
* rebase `HEAD~2` 或者更早
<a name="merge-conflict"></a>
@ -837,7 +837,7 @@ Changes not staged for commit:
有时候这些合并非常复杂,你应该使用可视化的差异编辑器(visual diff editor):
```sh
(master*)$ git mergetool -t opendiff
(main*)$ git mergetool -t opendiff
```
在你解决完所有冲突和测试过后, `git add` 变化了的(changed)文件, 然后用`git rebase --continue` 继续rebase。
@ -985,14 +985,14 @@ $ git update-ref refs/tags/<tag_name> <hash>
### 我只想改变一个文件名字的大小写,而不修改内容
```sh
(master)$ git mv --force myfile MyFile
(main)$ git mv --force myfile MyFile
```
<a href="remove-from-git"></a>
### 我想从Git删除一个文件但保留该文件
```sh
(master)$ git rm --cached log.txt
(main)$ git rm --cached log.txt
```
## 配置(Configuration)
@ -1048,21 +1048,21 @@ $ git config --global credential.helper 'cache --timeout=3600'
这就是 `git reflog` 的目的, `reflog` 记录对分支顶端(the tip of a branch)的任何改变, 即使那个顶端没有被任何分支或标签引用。基本上, 每次HEAD的改变, 一条新的记录就会增加到`reflog`。遗憾的是,这只对本地分支起作用,且它只跟踪动作 (例如,不会跟踪一个没有被记录的文件的任何改变)。
```sh
(master)$ git reflog
(main)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
```
上面的reflog展示了从master分支签出(checkout)到2.2 分支,然后再签回。 那里,还有一个硬重置(hard reset)到一个较旧的提交。最新的动作出现在最上面以 `HEAD@{0}`标识.
上面的reflog展示了从main分支签出(checkout)到2.2 分支,然后再签回。 那里,还有一个硬重置(hard reset)到一个较旧的提交。最新的动作出现在最上面以 `HEAD@{0}`标识.
如果事实证明你不小心回移(move back)了提交(commit), reflog 会包含你不小心回移前master上指向的提交(0254ea7)。
如果事实证明你不小心回移(move back)了提交(commit), reflog 会包含你不小心回移前main上指向的提交(0254ea7)。
```sh
$ git reset --hard 0254ea7
```
然后使用git reset就可以把master改回到之前的commit这提供了一个在历史被意外更改情况下的安全网。
然后使用git reset就可以把main改回到之前的commit这提供了一个在历史被意外更改情况下的安全网。
([摘自](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)).