1 the Git tools

1.1 Single submission

1.1.1 Log Reference

The checksum of a certain submission is displayed after show.

git show 9fceb0
Copy the code

View the last committed object for a branch.

git show master
Copy the code

View the checksum of the submitted object to which a branch points.

git rev-parse master
Copy the code

Git reflog uses @{n} to refer to the record output in git reflog. If HEAD@{n} is a commit record, output the commit record information; if not, output the last commit record of the branch. Note Reflog reference logs only record operations in the local repository. The newly cloned repository reference logs are empty.

git show HEAD@{2}
Copy the code

1.1.2 Ancestor Reference

View the parent commit information for a commit.

git show HEAD^
Copy the code

If a commit is a combined commit, there are multiple parent commits. ^n indicates the NTH parent commit of the current commit. If a merge commit has two parent commits, the first is the commit of the branch at the time of the merge and the second is the commit of the merged branch.

git show HEAD^2
Copy the code

Gets the corresponding first parent commit based on the specified number of times. The following is the first parent commit of the first parent, which is equivalent to HEAD^^.

git show HEAD~2
Copy the code

1.2 Submission Interval

C -- D <-- dev/A -- B -- E -- F <-- masterCopy the code

1.2.1 two point

Filter out commits that are in one branch but not another. The following command selects commits that are in the dev branch but not in the master branch, namely C and D commits.

git log master.. devCopy the code

You can also view certain commits that are to be pushed to the remote branch. Check the following for the commits pushed by the current branch to the remote master branch.

git log origin/master.. HEADCopy the code

1.2.2 ruled out

You can also add the ^ character or –not to indicate that you do not want to include a branch commit. These three commands are equivalent.

git log A.. B git log ^A B git log B --not ACopy the code

View commits that are included in A or B but not in C.

git log A B ^C
git log A B --not C
Copy the code

1.2.3 at 3 o ‘clock

Filter commits that are contained by one of two but not both. Check whether master or dev contains but does not include both common commits, namely E, F, C, and D.

git log master... devCopy the code

The usual –left-right argument shows which side of the branch each commit is on.

git log --left-right master... dev < F < E > D > CCopy the code

1.3 Interactive temporary storage

Run the git add -i command to enter the Git interactive terminal mode, where -i stands for –interactive.

           staged     unstaged path
  1:    unchanged        +1/-1 TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +1/-1 readme.md

*** Commands ***
  1: status       2: update       3: revert       4: add untracked
  5: patch        6: diff         7: quit         8: help
What now>
Copy the code

Wherein, staged lists are temporarily stored, unstaged lists are not temporarily stored, Commands are operation Commands, and What now is followed by numerical sequence number or command initial letter operation.

  • statusWith:git statusConsistent, more concise information
  • update: Temporary file, type2oruAfter the input file corresponding to the digital temporary file (multiple files used.Separate) before each file*This means that the selected file will be temporarily saved,>>Enter nothing after the prompt and press Enter to execute the command
  • revert: Cancel temporary storage
  • add untracked: Trace files
  • patch: Partial temporary file, similargit add -p
  • diff: Difference between staging area and last commit, similargit diff --cached
  • quit: Exits the interactive terminal
  • help: Command help

1.4 Partial temporary storage

Run the following command to temporarily save some changes, where -p is short for –patch.

git add -p
Copy the code

Each modified file is called a block or can be divided into several smaller blocks. The block command is as follows.

  • y: Temporarily store this block
  • n: This block is not temporarily stored
  • q: Exit, do not temporarily save the remaining blocks including this block
  • a: temporarily stores this block and all blocks following this file
  • d: does not temporarily store this block and all blocks following this file
  • g: Selects and jumps to a block
  • /: Searches for blocks that match the regular expression
  • j: Jumps to the next unprocessed block
  • J: Jumps to the next block
  • k: Jumps to an unprocessed block
  • K: Jumps to the previous block
  • s: Splits the current block into smaller blocks
  • e: Manually edit the current block
  • ?: Output help

1.5 storage

1.5.1 overview

Store changes that you don’t want to commit yet to the stack, and you can later recover the contents of the stack on a branch. You can restore not only to the original branch, but also to any other specified branch. The scope includes changes in the workspace and staging, meaning that uncommitted changes are saved to the stack.

1.5.2 to save

Saves uncommitted (workspace and staging) changes to the stack, excluding untraced files.

git stash
Copy the code

Uncommitted changes and untracked files are saved to the stack, where -u is short for –include-untracked, or git stash –all.

git stash -u
Copy the code

Saves workspace changes to the stack, excluding untraced files, where -k is short for –keep-index.

git stash -k
Copy the code

Save the file to the stack and make a note, where “message” is a note message.

git stash save 'message'
Copy the code

Save part of the changes to the stack, where -p is short for –patch.

git stash -p
Copy the code

1.5.3 view

Look at the contents of the stack.

git stash list
Copy the code

Run the following command to view the changes saved to a change on the stack (line increment and total for each change). The git stash show looks at the top of the stack, the most recent change saved to the stack.

git stash show stash@{3}
Copy the code

View the detailed differences of a change.

git stash show stash@{3} -p
Copy the code

1.5.4 application

Run the following command to apply a change to the current branch. Git Stash apply applies changes to the top of the stack.

git stash apply stash@{3}
Copy the code

File changes have been reapplied, but previously staged changes have not been recapitulated. The –index option reapplies the temporary changes.

git stash apply --index
Copy the code

1.5.5 to remove

To remove a change on the stack, the Git Stash drop removes a change at the top of the stack.

git stash drop stash@{3}
Copy the code

Apply a change to the stack and remove it. Git Stash drop applies and removes changes at the top of the stack. Note that if a conflict occurs when you execute git Stash pop, the change has already been applied, but it is still in the stack list. Remove the change manually.

git stash pop stash@{3}
Copy the code

Clear the stack list.

git stash clear
Copy the code

1.5.6 branch

Run the following command to generate a new branch from a change in the stack, check out the commit where the store was stored, then apply the change, and remove the change when successful. The Git Stash branch changes the top of the stack to create a new branch.

git stash branch dev stash@{3}
Copy the code

1.6 clean up

1.6.1 command

Git clean is used to remove untracked files from the working directory.

The main options are as follows. You can specify multiple options and abbreviate them.

  • -f:--forceShort, must be specified when deleting
  • -n:--dry-runShort for displaying files or folders to be deleted
  • -d: This parameter must be specified when deleting a folder
  • -xIncluding:.gitignoreIgnored files or folders
  • -X: a mere.gitignoreIgnored files or folders
  • -i: Interactive cleanup

View the list of files to be deleted.

git clean -n
Copy the code

View the files and folders that will be deleted.

git clean -d -n
Copy the code

Delete files that are not traced.

git clean -f
Copy the code

Delete files and folders that are not tracked.

git clean -f -d
Copy the code

Delete untraced files and files ignored by.gitignore.

git clean -f -x
Copy the code

Delete only files ignored by.gitignore.

git clean -f -X
Copy the code

Delete files and folders that are not tracked, files and folders that are ignored by.gitignore, or simply git clean-fdx.

git clean -f -d -x
Copy the code

1.6.2 Interactive Cleanup

Run git clean -i -d to enter interactive mode.

Would remove the following item:
  dist/ readme.md index.html
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers
    4: ask each             5: quit                 6: help
What now>
Copy the code

Would remove the following item from the list of files and folders to be cleaned.

  • clean: Clears files and folders in the list
  • filter by pattern: Exclude some files or folders from the clearing list. If the clearing list is empty, the system exits the interactive mode automatically
  • select by numbers: Select some files or folders in the clearing list. If the clearing list is empty, the system exits the interactive mode automatically
  • ask each: Query mode Deletes a list file or folder
  • quit: Exits the interactive mode
  • help: Command help

1.7 the search

Find a string or regular expression from the working directory.

Find the line in the working directory that contains the string A.

git grep A
Copy the code

Find the line in the working directory that contains the string A and display the line number.

git grep -n A
Copy the code

Find the file containing the string A.

git grep --name-only A
Copy the code

Count the number of lines of string A in A file where -c is short for –count.

git grep -c A
Copy the code

A line satisfies multiple conditions. The following command satisfies A line including A or B, where –or can be omitted.

git grep -e A --or -e B
Copy the code

A row contains A and A row contains B.

git grep -e A --and -e B
Copy the code

A row contains A and B or A and C.

git grep -e A --and \( -e B -e C \)
Copy the code

1.8 Interactive rebasing

It can be used to adjust the submission order, change the submission information in the submission or modify files, compress or split the submission, or remove the submission, etc.

1.8.1 Submission interval

D  d34...  <-- master HEAD
|
C  c23...
|
B  b12...
|
A  <-- HEAD~3
Copy the code

Run the following command to display the interactive base-changing interface, where the -i option is the submission record range, and the submission records from HEAD to 3 are B, C, and D. The end point of the interval can be omitted and defaults to the commit record pointed to by HEAD. Note that Git applies each commit change from top to bottom, with the earlier commit going up.

git rebase -i HEAD~3 HEAD

pick b12... B
pick c23... C
pick d34... D

# Rebase ... onto ... (3 commands)
Copy the code

1.8.2 Option Parameters

Some option parameters are as follows. Note that deleting a line of submission removes a line of submission, and all deletion changes will terminate.

  • pick: Preserves a commit
  • reword: Modifies the commit information of a commit
  • edit: Modifies a commit
  • squash: Merges a commit with a previous commit to modify the commit information
  • fixup: Merges a commit with the previous commit
  • drop: Removes a commit

1.8.3 Removing a Submission

Change pick to DROP, save and exit. The following will remove C’s submission information.

pick b12... B
drop c23... C
pick d34... D
Copy the code

1.8.4 Submission Sequence

Adjust the order of submitting records in the editor, save and exit. Change the submission sequence from B, C, and D to D, B, and C as follows.

pick d34... D
pick b12... B
pick c23... C
Copy the code

1.8.5 Modifying Submission Information

Change pick to reword, save and exit. The submission information of C and D will be modified as follows.

pick b12... B
reword c23... C
reword d34... D
Copy the code

After saving the Settings and exiting, the submission information editing page of C is displayed, and then the submission information editing page of D is displayed. Run git log –oneline to view the commit history.

d89... D'
c36... C'
b12... B
Copy the code

1.8.6 Compressed Submission

Compress multiple commits into a single commit, compress C and D to B as follows, and modify the commit information.

pick b12... B
squash c23... C
squash d34... D
Copy the code

Save and exit to modify the commit information.

# This is a combination of 3 commits.
# This is the 1st commit message:

B

# This is the commit message #2:

C

# This is the commit message #3:
    
D
Copy the code

You can also run the following command to skip the modification.

pick b12... B
fixup c23... C
fixup d34... D
Copy the code

1.8.7 Split Commit

Split one commit into multiple commits, which will be split commit C below.

pick b12... B
edit c23... C
pick d34... D
Copy the code

After you save and exit, HEAD points to commit C and run git reset HEAD^ to undo C’s commit but leave the changes intact. Then commit several more times and finally execute git rebase –continue to base.

git reset HEAD^
git add readme.md
git commit -m 'C1'
git add index.html
git commit -m 'C2'
git rebase --continue
Copy the code

Run git log –oneline to view the commit history.

d96... D
c35... C2
c46... C1
b12... B
Copy the code

1.9 erase

Overwrite a large number of submissions using a script that changes the mailbox address globally or removes a file from each submission.

The parameters of the filter-branch option are as follows:

  • --tree-filter: Runs the specified command after each commit of the checked item and resubmits the results
  • --prune-empty: Discard the modified submission if it is empty
  • -f:--forceShort for ignore backup force overwrite. An error occurs when erasing the second time, i.eGitBackup has been done last time, if run again will be processed last backup first
  • --all: Erases all branches
  • --index-filterAnd:--tree-filterA similar,--tree-filterCheck out each commit to the temporary directory and runfilterCommand to build a new commit based on the contents of the temporary directory. while--index-filterCopies each commit to the index and runsfilterCommand to build a new commit based on the contents of the index. That is, it is faster to build a commit from an index than from a directory

Erases the dist/index.html file from the dev branch’s entire commit history. If an error occurs, run git reflog to check the checksum submitted in the past and roll back the version.

git filter-branch -f --prune-empty --index-filter 'git rm -f --cached --ignore-unmatch dist/index.html' dev
Copy the code

Batch change the author and email address in the current branch submission history. Change the email address [email protected] to [email protected] and the author to B.

git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]; then GIT_AUTHOR_NAME="B"; GIT_AUTHOR_EMAIL="[email protected]"; git commit-tree "$@"; else git commit-tree "$@"; fi'
Copy the code

2 Advanced commands

2.1 File Set

HEAD is a pointer to the current branch reference, always pointing to the last commit on that branch.

Index is the expected next commit and can be referenced as a staging area.

Working Directory is a Working Directory.

2.1.1 to submit

Git init Creates a Git repository where the HEAD reference points to an uncreated branch (the master does not yet exist). A branch is a pointer to a commit, and the initialized repository has no commit record, so there is no branch by default.

? <-- master <-- HEAD
Copy the code

Create a new file readme.md in the working directory (version v1 for now).

-- - the HEAD -- -- -- -- the Index -- -- -- -- Working Directory? ? readme.md (v1)Copy the code

Git add gets the contents of the working directory and copies them into Index.

-- - the HEAD -- -- -- -- the Index -- -- -- -- Working Directory? readme.md (v1) readme.md (v1)Copy the code

Git commit Saves the contents of the Index as a snapshot, then creates a commit object pointing to the snapshot, and updates the master pointing to the commit object.

V1 <-- master <-- HEAD ———— HEAD ———————— Index ———————— Working Directory readme.md (v1) readme.md (v1) readme.md (v1)Copy the code

Change the file from your working directory to version V2 and run Git status to see Changes not staged for COMMIT.

V1 <-- master <-- HEAD ———— HEAD ———————— Index ———————— Working Directory readme.md (v1) readme.md (v1) readme.md (v2)Copy the code

Run git status to see Changes to be committed.

V1 <-- master <-- HEAD ———— HEAD ———————— Index ———————— Working Directory readme.md (v1) readme.md (v2) readme.md (v2)Copy the code

Commit this change. Master points to version V2.

V1 -- v2 <-- master <-- HEAD ———— HEAD ———————— Index ———————— Working Directory readme.md (v2) readme.md (v2) readme.md  (v2)Copy the code

2.1.2 reset

Git reset is a rollback of the git reset version, modify readme.md, and commit the commit history as follows.

V1, v2, v3 < - master < - HEAD -- - HEAD -- -- -- -- the Index -- -- -- -- Working Directory readme. Md (v3) readme. Md (v3) readme.md (v3)Copy the code

The first step is to move the HEAD, that is, move the master to v2, and then move the HEAD to master. To do this, run git reset –soft HEAD^ to undo the v3 commit and run git commit again to do what git commit –amend does.

V3 / v1, v2 < - master < - HEAD -- - HEAD -- -- -- -- the Index -- -- -- -- Working Directory readme. Md (v2) readme. Md (v3) readme.md (v3)Copy the code

The second step is to update Index, which is to update the staging area. You can do this by running git reset –mixed HEAD^, where –mixed can be omitted to essentially undo the v3 commit and unhold all changes.

V3 / v1, v2 < - master < - HEAD -- - HEAD -- -- -- -- the Index -- -- -- -- Working Directory readme. Md (v2) readme. Md (v2) readme.md (v3)Copy the code

The third step is to update the working directory to be consistent with Index. Git reset –hard HEAD^ forces v2 in Index to overwrite the working directory.

V3 / v1, v2 < - master < - HEAD -- - HEAD -- -- -- -- the Index -- -- -- -- Working Directory readme. Md (v2) readme. Md (v2) readme.md (v2)Copy the code

2.1.3 Revoke temporary storage

Modify readme.md and save it temporarily, with the following commit history.

V1 <-- master <-- HEAD ———— HEAD ———————— Index ———————— Working Directory readme.md (v1) readme.md (v2) readme.md (v2)Copy the code

Run git reset readme.md (git reset –mixed HEAD readme.md) to copy the readme.md from HEAD to Index.

V1 <-- master <-- HEAD ———— HEAD ———————— Index ———————— Working Directory readme.md (v1) readme.md (v1) readme.md (v2)Copy the code

Git reset 5f5292 readme.md, where 5f5292 is the checksum of a committed file.

F5292 v1 (5), v2, v3 < - master < - HEAD -- - HEAD -- -- -- -- the Index -- -- -- -- Working Directory readme. Md (v3) readme. Md  (v1) readme.md (v3)Copy the code

2.1.4 compression

If A project has been submitted three times recently, submit A to add readme.md for the first time, submit B to modify readme.md and add index.txt for the second time, and submit C to modify readme.md again for the third time. Since B and C are both committed to modify the same function, they need to be compressed.

C readme.md (v3) index.txt (v1) <-- master <-- HEAD/B readme.md (v2) index.txt (v1)/A readme.md (v1) ———— HEAD ———————— Index ———————— Working Directory readme.md (v3) readme.md (v3) readme.md (v3) index.txt (v1) index.txt (v1) index.txt (v1)Copy the code

Run git reset –soft HEAD^^ to move the HEAD onto commit A.

TXT (v1)/B readme.md (v2) index.txt (v1)/A readme.md (v1) <-- master <-- HEAD ———— HEAD ———————— Index ———————— Working Directory readme.md (v1) readme.md (v3) readme.md (v3) index.txt (v1) index.txt (v1)Copy the code

Run git commit to compress the changes B and C into a new commit D.

C readme.md (v3) index.txt (v1) | B readme.md (v2) index.txt (v1) | D readme.md (v3) index.txt (v1) <-- master <-- HEAD | / A readme. Md (v1) -- -- - HEAD -- -- -- -- the Index -- -- -- -- Working Directory readme. Md (v3) readme. Md (v3) readme. Md (v3) index.txt (v1) index.txt (v1) index.txt (v1)Copy the code

2.1.5 branch

The commit history of the branch is as follows: the current HEAD points to the master branch.

B readme. Md (v2) < -- -- master < -- the HEAD/A readme. Md (v1) < - dev - - the HEAD - - - - the Index -- -- -- -- Working Directory readme.md (v2) readme.md (v2) readme.md (v2)Copy the code

Git checkout dev moves the HEAD to the dev branch. Unlike Git reset –hard HEAD, only moves the HEAD itself, and checkout checks for uncommitted changes to prevent them from getting lost.

B readme. Md (v2) < -- master/A readme. Md (v1) < -- dev < - HEAD -- - HEAD -- -- -- -- the Index -- -- -- -- Working Directory readme.md (v1) readme.md (v1) readme.md (v1)Copy the code

2.2 Advanced Merge

2.2.1 Option Parameters

  • --continue: In some cases merging creates conflicts,GitWill pause for conflict resolution. One way to do that isgit addMark the conflicting files as resolved and submit them again. Another way is to tag and executegit merge --continueContinue merging. If no conflicts arise,GitA merge commit is automatically created
  • --abort: Attempts to restore to the pre-merge state. When there are uncommitted changes in the working directory,git merge --abortIn some cases, the pre-merge state cannot be reproduced. Therefore, it is recommended to keep a clean working directory before merging, which can be partially modified throughgit stashStorage, conflict resolution and then release
  • -Xignore-all-spaceIf there is no difference between the merged branch and the current branch except for Spaces, ignore the merged branch file. whenAmergeBChange,AModified tohello wor ld, B is changed tohello wo rld, the two changes are equivalent, and the combined changes are ignoredB
  • -Xignore-space-change: Ignores the change in the amount of space. If one line has a space in a non-trailing position and the other does not, it is treated as a conflict. whenAmergeBChange,AModified tohello*world(the abutment* Instead of Spaces),BModified tohello**world, the two changes are equivalent, and the merged changes are ignoredB.AModified tohelloworld.BModified tohello world, the two changes conflict

2.2.2 Conflict Status

To view the unmerged files, run the following command. This includes version 1 of their common ancestor, current version 2 (HEAD), and merged version 3 (MERGE_HEAD).

git ls-files -u
100644 ac5336... 1	readme.md
100644 36c569... 2	readme.md
100644 e85456... 3	readme.md
Copy the code

Git cat-file -p :2:readme.md git cat-file -p :2:readme.md

git cat-file -p 36c569
Copy the code

After a conflict file is modified (not temporarily saved), you can run the following command to view the difference. Where –base refers to the difference between the modified version and the version of their common ancestor, –theirs refers to the difference between the modified version and the merged version, and –ours refers to the difference between the modified version and the current version.

git diff [--base|--ours|--theirs]
Copy the code

2.2.3 Conflict detected

The master branch modifies the readme.md file, and the dev branch modifies the readme.md file. The current HEAD points to the master branch. If the dev branch modifies the readme.md file, the following conflicts will occur.

<<<<<<< HEAD
  puts 'hi world'
=======
  puts 'hello git'
>>>>>>> dev
Copy the code

At this time, we do not know which modification is reserved and there is no more reference information. Run the following command to check the differences of ours, base and theirs versions. Git config –global merge. Conflictstyle Diff3 is the default format for merging conflicts.

git checkout --conflict=diff3 readme.md

cat readme.md
<<<<<<< ours
hi world
||||||| base
hello world
=======
hello git
>>>>>>> theirs
Copy the code

Run the following command to quickly preserve one side’s changes. Ours indicates to keep the current change and discard the introduced change. — Theirs means keep the introduced changes and discard the current changes.

git checkout [--ours|--theirs] readme.md
Copy the code

2.2.4 Merging Logs

The commit history of the master and dev branches is as follows: the current HEAD points to the master. The readme.md file is modified for submission B and D, index. TXT is added for submission C, and file.txt is added for submission E.

C index.txt (v1) <-- master <-- HEAD | B readme.md (v3) | E file.txt (v1) <-- dev | / | D readme.md (v2) | / A readme.md  (v1)Copy the code

Git merge dev after a conflict occurs, you can run the following command to view all independent commits for each branch involved in the git merge.

git log --oneline --left-right HEAD... MERGE_HEAD < f127062 B < af9d363 C > e3eb226 D > c3ffff1 ECopy the code

Add the –merge option to show only the commits of files that are in contact with merge conflicts on either side. You can also add the -p option to view the differences between all conflicting files.

git log --oneline --left-right --merge
< f127062 B
> e3eb226 D
Copy the code

2.2.5 Merging Policies

Run the following command. If there are changes that can be merged, Git will merge them directly, and if there are conflicting changes, Git will select the specific changes based on the option parameters. The -xours option gives priority to the current HEAD change when a conflict occurs, the -xtheirs option gives priority to the dev branch change, and the rest changes that can be merged are merged directly.

git merge [-Xours|-Xtheirs] dev
Copy the code

2.3 Reusing merged Records

Reuse Recorded Resolution lets Git remember how to resolve a block conflict and resolve it automatically the next time it sees the same conflict.

To enable rerere, create the RR-cache folder in the. Git directory.

git config --local rerere.enabled true
Copy the code

2.3.1 Record Conflict

The readme.md of each branch is modified as follows.

C readme.md (hello git) <-- master <-- HEAD/A readme.md (hello world) -- B readme.md (hi world) <-- devCopy the code

Merge the readme.md changes in the dev branch with the master branch. Recorded PreImage indicates that Git has started tracking the merge.

git merge dev
Auto-merging readme.md
CONFLICT (content): Merge conflict in readme.md
Recorded preimage for 'readme.md'Automatic merge failed; .Copy the code

View the readme.md file.

cat readme.md
<<<<<<< HEAD
hello git
=======
hi world
>>>>>>> dev
Copy the code

Git /rr-cache/0ff6a9/preimage is the version before the merge conflict, where 0ff6a9 is the checksum of the conflict.

<<<<<<<
hello git
=======
hi world
>>>>>>>
Copy the code

Process readme.md, mark it as resolved and commit. Recorded Resolution indicates that the resolution of the conflict is Recorded.

git add readme.md
git commit -m 'D'
Recorded resolution for 'readme.md'. [master ...]  DCopy the code

The post-conflict submission history is as follows.

   B readme.md (hi world)  <-- dev
 /                        \
A readme.md (hello world)   D readme.md (hi git) <-- master <-- HEAD
 \                        /
   C readme.md (hello git) 
Copy the code

Git /rr-cache/0ff6a9/postimage Essentially when Git sees a block conflict in a readme.md file with Hi world on one side and Hello Git on the other, it will resolve it to hi Git.

hi git
Copy the code

Undo merge commit D, then merge dev’s changes again. The Resolved… Using previous resolution indicates that a previous merge record is used.

git reset --hard HEAD^
git merge dev
Auto-merging readme.md
CONFLICT (content): Merge conflict in readme.md
Resolved 'readme.md'using previous resolution. Automatic merge failed; .Copy the code

View the readme.md after using the merged record.

cat readme.md
hi git
Copy the code

Git merge –abort the merge and return to the previous state. Let’s look at the case where we base the dev changes to master.

git switch dev
git rebase master
...
Resolved 'readme.md' using previous resolution.
....
Copy the code

Git add marks the file as resolved and git rebase –continue with B’. Master becomes the direct upstream of the dev branch.

B' <-- dev <-- HEAD | C <-- master | B | / ACopy the code

2.3.2 Recovering a Conflict

Git automatically resolves the conflict, but you may have forgotten the readme.md state at the time of the conflict. Run the following command to restore the readme.me state at the time of the conflict.

git checkout --conflict=merge readme.md
cat readme.md
<<<<<<< ours
hello git
=======
hi world
>>>>>>> theirs
Copy the code

2.3.3 Application Scenarios

The branch commit history is as follows.

E -- F <-- dev/A -- B -- C <-- masterCopy the code

In some cases, the changes to the master branch are merged to test whether the changes to the dev branch affect some of the functions of the master branch.

E, F, G < - dev / / A -- -- -- -- -- B C < - masterCopy the code

It is possible to merge multiple times from the master branch to the dev branch for testing, and eventually the master branch merges the changes from the dev branch. If you look at the master branch commit history, you might see a lot of merge records. The history tree doesn’t seem intuitive.

         E —— F —— G —— H —— K —— L <-- dev
       /         / /A - B \ C -- -- -- -- -- -- -- -- < J, M, N - masterCopy the code

The dev branch can discard the merge record each time the master branch completes the test, because Rerere has already recorded the resolution of the conflict, so there is no need to worry about merging again. Finally, the dev branch completes the development and merges with the Master branch, and commits the history tree as follows:

E, F, H - L < - dev / \ A - B - C - J, M, N < - masterCopy the code

2.4 Restore Submission

Commits include regular commits, which have only one parent commit, and merge commits, which have two or more parent commit objects. Git reset –hard cancels a commit, but can cause major problems for commits that have been pushed to a remote repository. Another solution is to restore commit, which generates a new commit that will undo the changes specified for one of the commits.

2.4.1 General submission

If the branch commit history is as follows, where HEAD points to master.

(A - B24e888-- C <-- master <-- HEADCopy the code

Run the following command to undo the change in B or git revert HEAD^.

git revert 24e888
Copy the code

After running Git will open Vim editor, you can modify the new commit information.

Revert "B"

This reverts commit 24e888. # Please enter the commit messagefor your changes. Lines starting
# with The '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
...
Copy the code

The final submission history is as follows.

A —— B —— C —— ^B <-- master <-- HEAD
Copy the code

2.4.2 Merge Submission

The commit history of each branch is roughly as follows: HEAD points to the master branch, where D is a merge commit, and the rest are regular commits.

A, B, C, D (110 c0d6) - G < - master < - HEAD \ / E - F < - devCopy the code

In some cases, the dev branch’s merged changes are found to be so flawed that they need to be discarded, i.e. the changes committed twice by E and F. If you run Git resert 110c0d6 to undo commit D and Git doesn’t know which branch changes to undo, you need to tell Git which branch changes to keep, and the other branch changes will be undone. Run the following command to create the restore commit ^D, where -m indicates that the cancelled commit is a merge commit, and 1 indicates that the changes of the first parent commit C of commit D are retained and the changes of E and F are undone.

git revert -m 1C0d6 110 A, B, C, D (110 c0d6) - G - ^ D < - master < - HEAD \ / E - F < - devCopy the code

When a major defect in the Dev branch is fixed, it can be merged back into the master. It may seem intuitive that all changes from E, F, and H are merged into the master branch, but note that the master does not include changes from E and F, i.e. only changes from H are merged into the master branch.

A - B - C - D - G - ^ D - I < - master < - HEAD \ / / E -- -- -- -- -- -- -- -- H F < - devCopy the code

The solution to the above situation is also easy, undo to undo, that is, undo ^D changes first. Git revert HEAD d6d7365 is a partial checksum submitted to ^D.

Git revert d6d7365 A -- B -- C -- D -- G -- ^D (d6d7365) <-- master <-- HEAD \ / E -- F -- H <-- devCopy the code

Git merge dev

- A - B - C - D - G ^ - ^ D ^ D - I < - master < - HEAD \ / / E - F -- -- -- -- -- -- -- -- -- -- - H < - devCopy the code

2.5 Debugging Tools

2.5.1 Document Annotation

View the last modification committed for each line of a file. The first field in each line of output is the partial checksum of the submission of the last modified line, and the beginning ^ represents the submission of the file when it was first added to the project. The fields in brackets are author, submission time (including time zone), and line number. The last is the content of a certain line.

Look at lines 2 through 5 of the file. -l indicates the range, and 2,5 indicates the second to fifth lines, which are closed ranges. If no -l parameter or range is specified, all lines of the file are viewed.

git blame -L 2.5 readme.md
^4832fe2 (DonG 2021-01-12 10:31:28 +0800 2)   hello
9f6560e4 (DonG 2021-01-13 10:32:29 +0800 3)   world
cd564aa5 (DonG 2021-01-14 10:33:30 +0800 4)   and
7f3a6645 (DonG 2021-01-15 10:34:31 +0800 5)   git
Copy the code

The range can also specify the number of rows, with + for down and – for up. If the following three lines from the second line down are displayed, the submission information of lines 2, 3, and 4 is displayed.

git blame -L 2, +3 readme.md
Copy the code

2.5.2 Binary Search

The bisect command does a binary lookup of the commit history to help find out as quickly as possible which commit introduced the problem.

The submission history is as follows: A bug feedback was received in submission C101, but there was no such bug in submission C1. It can be confirmed that the submission between submission C1 and submission C101 introduced a bug.

C1 (d564AA) -- C2 ··· C50 ··· · C100 -- C101 <-- master <-- HEADCopy the code

Run the following command to select the commit history from C1 to C101 for binary lookup. The code base will switch to the commit C51 in the proper range, where D564AA is the partial checksum of the commit C1.

git bisect start HEAD d564aa
Copy the code

The bug is repeated under C51 submission and does not exist, indicating that it is between C52 and C101. Good indicates that there is no problem with C51 submission this time.

git bisect good
Copy the code

Git automatically switches to the midpoint between C52 and C101 to commit C76.

git bisect bad
Copy the code

You repeat this process, eventually finding the commit that went wrong and printing out the details of that commit.

857293.. is the first bad commit commit857293..Author:...Date:...Copy the code

Run the following command to exit the error check and return to the last code submission.

git bisect reset
Copy the code

2.6 packaging

Git can package branch content into a binary file for mail or other transmission.

Repo. bundle is the binary file name generated by the package.

git bundle create repo.bundle HEAD master
Copy the code

Clone the binary file generated by packaging, where repos is a customized repository name and can not be specified. Repo is the default.

git clone repo.bundle repos
Copy the code

Package a range of commit records, where HEAD^^.. HEAD open left and close right interval, that is, D and E submit records twice.

git bundle create repo.bundle HEAD^^.. HEAD master A -- B -- C -- D -- E <--master <-- HEADCopy the code

Check if the file is a valid Git package and has a common ancestor to import. The bundle requires this ref. The bundle requires this ref. The bundle requires this ref.

git bundle verify repo.bundle
...
The bundle requires this ref:
99884a...
Copy the code

View branches that packages can import.

git bundle list-heads repo.bundle
Copy the code

The master branch of the import package is committed to the local dev branch.

git fetch repo.bundle master:dev
Copy the code

2.7 Credential storage

When Git uses HTTP to access remote repositories, each connection requires a user name and password.

Git provides a credential system to solve this problem. Some of the options are as follows.

  • Default: Credentials are not cached and the user name and password are asked for each connection
  • cache: Stores credentials in memory for a period of time, passwords are not stored in disk, and15It is cleared from memory after minutes. Note that this option does not applywindowsSystem as this option is passedunixThe socket communicates
  • store: The credentials are stored in the disk in plain text and never expire. The default path isC:/Users/{username}/.git-credentials
  • manager: Managed by credentialswindowsCredential manager in the system, which can be viewed in the credential manager for user accounts in the control panel

Run the following command to configure the options.

git config --global credential.helper [cache|store|manager]
Copy the code

The default Git installation mode is Manager. To Enable Git Credential Manager, Enable Git Credential Manager

The user name and password entered in the following window will be logged by the credential manager.

3 modules

A submodule is a Git repository that acts as a subdirectory of another Git repository, independent of each other, while one repository depends on the other.

3.1 add

The repository adds submodules, which by default are placed in the directory with the same name as the repository, that is, subrepo is generated in the main project.

git submodule add https://github.com/username/subrepo.git
Copy the code

You can also specify a subdirectory name or path at the end of the command. Subrepos is generated in the following main project.

git submodule add https://github.com/username/subrepo.git subrepos
Copy the code

Note that the submodule clones the master branch of the repository by default. Run the following command to clone the specific branch, where -b is short for –branch and dev is the branch of the remote repository subrepo.

git submodule add -b dev https://github.com/username/subrepo.git
Copy the code

3.2 check the

Run git status under the main menu to check the status. Note that when you add a submodule for the first time,.gitmodules files will be generated and are temporary, and.gitmodules will also be tracked and managed by Git.

git status
...
Changes to be committed:
  ...
        new file:   .gitmodules
        new file:   subrepo
Copy the code

The. Gitmodules file saves the mapping between the URL of the submodule project and the local directory. Note that there are multiple submodules in the main project, and.gitModules will have multiple records.

cat .gitmodules
[submodule "subrepo"]
        path = subrepo
        url = https://github.com/username/subrepo.git
Copy the code

Looking at the difference between the staging area and the most recent repository, although subrepo is a subdirectory of the main project directory, Git does not keep track of its contents, but treats it as a special commit in the repository.

git diff --cached
...
+[submodule "subrepo"]
+       path = subrepo
+       url = https://github.com/username/subrepo.git. +Subproject commit 3b8ad09...Copy the code

You can also specify the — subModule option to see the differences.

git diff --cached --submodule
...
+[submodule "subrepo"]
+       path = subrepo
+       url = https://github.com/username/subrepo.git
Submodule subrepo 0000000. 3b8ad09 (new submodule)
Copy the code

3.3 submit

Run a Git Commit under the main project, where 160000 is a special mode in Git where the submodule directory is essentially pointing to a commit.

git commit -am 'message'. create mode100644 .gitmodules
 create mode 160000 subrepo
Copy the code

Run the following command to view the current commit tree object, where the current version in subrepo points to the commit record 3b8AD09.

git ls-tree -r HEAD
100644 blob 9a5259...    .gitmodules
160000 commit 3b8ad09...  subrepo
Copy the code

3.4 the cloning

Clone repository repo, which contains submodule subrepo. By default, clone repository repo will contain submodule directory subrepo, but there are no files.

git clone https://github.com/username/repo.git
Copy the code

Run the following command to initialize the local configuration. If you want to verify the implementation of this method, you can first clone the repository repo, and then enter the repository. Git folder, run git init, temporarily save all files and commit, use git to trace the changes in git, then go back to the parent, run git diff, and finally enter. You can see related files changed after this command is executed. This method can also verify the execution of other Git commands.

git submodule init
Submodule 'subrepo'(...). registeredfor path 'subrepo'
Copy the code

After initializing the local configuration, run the following command to capture the files of the corresponding version in the submodule. Note that Git will pick up the changes and update the files in the subdirectory, but it will leave the subrepository in a floating HEAD state. There is no local branch to track the changes, so you can perform Git checkout to checkout the corresponding working branch.

git submodule update
Copy the code

You can also run the following command to automatically initialize and update each submodule in the warehouse.

git clone --recursive https://github.com/username/repo.git
Copy the code

The 3.5 update

It is possible to use only submodule projects to get updates from time to time, but not to make changes in submodules.

The following are updated inside and outside the submodule, where the submodule directory is included under the main project repo.

3.5.1 track of internal

Submodule subrepo run Git Fetch and Git Merge to merge the latest code. You can also view the code submission history and differences of submodule subrepo. Note that if you cannot fetch the latest code at this time, you may need to run git checkout to checkout the working branch because subrepo is in a free HEAD state.

After the merge update is returned to the main project repo, the subrepo update will be recorded by the repository repO as a new special change. You can run git status to check the status of the working directory, or run the following command to check the change of the commit record pointed to by the subrepo directory and the commit information for the currently pointed commit. Six cc07e3.. 81AFAE7 indicates that the submission record pointing to submodule subrepo is updated from 6CC07e3 to 81AFAE7. The current submission information of submission record 81AFAE7 is Update subrepo readme.md.

git diff --submodule Submodule subrepo 6cc07e3.. 81afae7: > update subrepo readme.mdCopy the code

3.5.2 external

To update the subrepo code in the main project repo, run the following command to update the code for all submodules in the repository repo.

git submodule update --remote
Copy the code

There may be many submodules, and only one submodule needs to be updated, as shown below, only subrepo is updated.

git submodule update --remote subrepo
Copy the code

Run the following command to change the version mapping of submodule subrepo to another branch, where dev is the branch name, and then run git submodule update –remote subrepo.

git config -f .gitmodules submodule.subrepo.branch dev
Copy the code

3.6 push

Submodule subrepo modifies some files. If the warehouse subrepo is in the free HEAD state, it also needs to check out the corresponding work branch, and no changes are pushed after submission. When you commit and push in the main project REPo, and someone else updates the subrepo, you can’t get the changes that the submodule depends on, and those changes only exist in the local copy.

Run the following command, Git will check whether the submodule has been pushed when pushing the main item. If any changes of the submodule are not pushed, push will fail.

git push --recurse-submodules=check
The following submodule paths contain changes that can
not be found on any remote:
  subrepo
...
Copy the code

Run the following command to push changes of submodules in the main push item. Note that if the submodule fails to push for some reason, the main project also fails to push.

git push --recurse-submodules=on-demand
Copy the code

3.7 combined

Others who change references to submodules at the same time may encounter partial problems that require some work to fix.

3.7.1 fast forward

If the primary project repo includes subproject subrepo, both user A and user B clone the remote warehouse REPO. User A modifies the files under the subproject, commits and pushes subrepo and repo. Without making any changes, user B performs Git pull, and the subrepo project will do a fast-forward merge, which Git will select later commits to merge.

git pull
...
Fetching submodule subrepo
...
Fast-forward
 subrepo 
Copy the code

3.7.2 Submodule Conflict

If the primary project repo includes subproject subrepo, both user A and user B clone the remote warehouse REPO. Subrepo contains the file readme.md (v1).

User A modifies readme.md (v2), commits and pushes changes in both repo and Subrepo.

User B modifies readme.md (v3), commits the changes to both repo and Subrepo, and then pulls the pushed changes from user A.

git pull
...
Failed to merge submodule subrepo (merge following commits not found)
Auto-merging subrepo
CONFLICT (submodule): Merge conflict in subrepo
...
Copy the code

Merge following commits not found Merge commits v2 and v3 were not found in the subrepo.

Run git diff to check the checksum of the two conflicting commit records, where 2ceb726 is the checksum of user B’s commit and 29b9770 is the checksum of user A’s commit.

Git diff index 2 ceb726, 29 b9770.0000000.
Copy the code

Go to the submodule directory subrepo, which should currently point to commit 2ceb726, and run the following command to create A temporary branch of user A’s changes.

git branch theirs 29b9770
Copy the code

Merge the THEIRS branch, and here you get a real merge conflict. Mark the file readme.md (V4) as resolved, commit and push the changes to subrepo, and finally go back to the main project repo to commit and push the changes.

git merge theirs
...
CONFLICT (content): Merge conflict in readme.md
...
Copy the code

Another merge method is that after user A commits and pushes, user B’s readme.md (v3) modifs the commit, executes Git pull to merge V2 and v3 into V4, pushes the merge version, and then returns to the repo commit of the main project.

Finally, git pull is executed, and user A’s readme.md (v2) modification is introduced. Since Git found the merge commit version V4 for v2 and V3, the merge is only A simple fast-forward merge.

git pull
...
Fast-forwarding submodule subrepo
Auto-merging subrepo
Merge made by the 'recursive' strategy.
Copy the code

3.8 delete

If the main project repo deletes submodule subrepo, Git will delete submodule directory subrepo and update.gitmodules, temporarily saving the above changes.

git rm -f subrepo
Copy the code

Then delete subrepo in.git/config.

[submodule "subrepo"]
        url = https://github.com/username/subrepo.git
Copy the code

Finally, commit and push changes under the main project REPO.

3.9 other

3.9.1 Traversal of Submodules

Git will run Git Checkout Master in each submodule by running the following command in the main project.

git submodule foreach git checkout master
Copy the code

3.9.2 Switching Branches

The main project repo does not add submodules for the time being. Subrepo is added and committed after a new branch dev is checked out.

git checkout -b dev
git submodule add https://github.com/username/subrepo.git
git commit -am 'message'
Copy the code

Switch to the master branch and warn not to delete subrepo that is not empty.

git checkout master
warning: unable to rmdir 'subrepo': Directory not empty
Switched to branch 'master'.Copy the code

The master branch should have no submodules, but it still has an untraced submodule directory, subrepo.

git status
...
Untracked files:
  ...
        subrepo/
Copy the code

Run rm -r subrepo to delete the submodule directory, and then switch back to the dev branch with git switch. But there are no files in the subrepo directory. Run the following command to rebuild and populate the submodule subrepo.

git submodule update --init
Submodule path 'subrepo': checked out ...
Copy the code

3.9.3 subdirectories

If the repository repo contains subdirectory subrepo, subrepo contains partial files, the repository repo contains the master and dev branches, and HEAD points to the dev branch.

The submodule subrepo was added, but the addition failed because the subrepo directory existed.

git submodule add https://github.com/username/subrepo.git
'subrepo' already exists in the index
Copy the code

Run the following command to delete the subrepo directory and then add the submodule, and then commit the changes.

git rm -r subrepo
Copy the code

Switch the branch to master and notice that the files in the subdirectory subrepo are merged with the files in the submodule of the dev branch.

The solution is to first delete the subrepo directory, then undo the changes, and finally restore the subrepo directory on the Master branch.

rm -r subrepo
git checkout .
Copy the code

In the previous

The next article