Local testing environment: macOS 11
14 | How to delete unnecessary branches?#
git branch -d <BRANCH_NAME>
-d
:--delete
- Conditionally delete a local branch
- ❗️Condition: The deletion can only be successfully executed when the branch has been merged into the upstream branch (the remote branch corresponding to the local branch, which can be set) or HEAD (the current branch).
git branch -D <BRANCH_NAME>
-D
:--delete --force
- Force delete a local branch
- Can be used when it is confirmed that deleting the branch poses no risk.
PS:
- Cannot delete the current branch; to delete it, switch branches first using
git checkout <BRANCH_NAME>
. - To delete a remote branch:
git push <REMOTE> --delete <BRANCH_NAME>
- Synchronize the branch list using
git fetch -p / --prune
, at which point remote branches that have been deleted will no longer be displayed.
- Synchronize the branch list using
15 | How to modify the message of the latest commit?#
Enter git commit --amend
, which will open a text editor to modify the new commit message, as shown in the red box:
After entering :wq
to save and exit, the terminal will display the modification result:
Check the commit information again:
Modification successful!
PS: git commit --amend
- Essentially replaces the last commit, not limited to modifying the message.
- Generally used to modify commit operations that have not been pushed to the remote yet.
16 | How to modify the message of an old commit?#
git rebase -i
can be used to modify the messages of the previous commits, where -i
is for interactive mode.
——Specific Steps——
First, use git log
to view the current version history:
If we want to modify the message of the third commit in order, we need to operate based on its parent commit.
Use the command git rebase -i d8796c00719323800976e6c7fcfe6b02627ec6b2
, adding the hash value of the parent commit at the end (if you want to modify the very first commit, you can use git rebase -i --root
), which will open the editing interface:
The order of commits has been reversed; you can see many usages in the Commands section.
We use the reword / r
command to keep a certain commit but modify its message, as follows:
After saving and exiting with :wq
, a new editing interface will pop up:
Modify the commit message, then :wq
to save and exit.
Modification successful, ❗️you can see that a detached HEAD was used here, and after the modification, the master branch's pointer was updated, indicating that the commit's hash value is likely to have changed.
Let's verify it by checking the version history again with git log
:
It can be seen that the message of the third commit has been successfully modified, and the hash values of the first three commits have all changed. Except for the message of the third commit, no other information has actually changed, which can be verified independently.
⚠️:
- Generally used on your own branch before it has been submitted to the integration branch (team); otherwise, be cautious, as it will affect the integration branch.
rebase
is commonly used for rebasing; you can pay attention to its similarities and differences withmerge
, refer to:- Git Branch - Rebase——Official
- The Correct Posture for Using rebase and merge in GIT——Zhihu
17 | How to organize multiple consecutive commits into one?#
Also use git rebase -i
——Specific Steps——
First, use git log
to view the current version history:
Now we want to merge the three commits in the red box above to reduce the number of commits in the branch.
Use the command git rebase -i --root
, adding the hash value of the parent commit at the end (since we want to modify the very first commit, we use --root
), which will open the editing interface:
The three commits to be merged are shown in the red box above, and their order is the reverse of what is displayed in git log
.
Using the squash / s
command from the Commands section, we can merge a commit into the previous one, modifying as follows:
After saving and exiting with :wq
, a new editing interface will pop up:
Add a second line as the message for merging the three commits, keeping the messages of each commit below, then :wq
to save and exit.
Integration successful, ❗️you can see that a detached HEAD was used here, and after the modification, the master branch's pointer was updated.
git log
also verifies the integration result, and it can be seen that the hash values of the two commits have changed because the commit messages or the pointers of the parent commits have changed.
PS:
- After integration, some commits will become obsolete, and git will perform cleanup.
- Use
gitk --all
to observe the branch situation at this time:
- It can be seen that two trees have appeared, and there is no longer any association between the two branches.
- This is because the root commit of the master branch has changed.
18 | How to organize several spaced commits into one?#
Command: git rebase -i
Use the git log
command to view the version history:
Want to merge the spaced commits shown in the red box, also use the command git rebase -i 76e5c9ca
, adding the hash value of the parent commit at the end, which will open the familiar window:
Adjust the positions of the commits to be merged and use the s
command, modifying as follows:
After saving and exiting with :wq
, it prompts that there are merge conflicts that need to be resolved.
The blue box above indicates the operations that can be performed next; here we try the first method: resolve the conflicts.
PS: You can also use git status
to see the current suggested operations:
Next, check the readme file to resolve the conflicts inside by deleting the code at the red box position:
Then run git add readme
to add the modification record.
Then, run git rebase --continue
as prompted, which will open the editing box to enter the message, and :wq
to save and exit (you may need to resolve conflicts again and repeat the above steps).
Finally, use git log
to check the version history:
It can be seen: if the spaced commits are related to the commits to be merged, it may not meet expectations, causing them to be merged into one commit, so you need to be very clear about the content of these commits.
PS: Personally, I think this is not very practical and can easily lead to conflicts.
19 | How to compare the differences between the staging area and the files contained in HEAD?#
Command: git diff --cached
Don't forget this picture:
- HEAD points to the current branch, and the branch points to a commit.
Demonstration:
After modifying the readme.md file, enter git add readme.md
to add the modification to the staging area;
Then enter git diff --cached
to compare the differences between the staging area and HEAD:
It can be seen that two lines of text have been added; after confirming that it meets expectations, you can commit.
20 | How to compare the differences between the working directory and the files contained in the staging area?#
Command: git diff
You can also add a filename after the command to compare the differences of a specific file in the working directory and the staging area, such as git diff readme.md
, and you can also add multiple filenames.
21 | How to make the staging area restore to be the same as HEAD?#
Scenario: The content in the staging area is no longer needed, staging area 👉 HEAD.
Command: git reset HEAD
, without adding anything after HEAD
, will restore all files to be consistent with HEAD
.
You can observe the changes before and after reset
using git status
, as shown in the figure below:
After reset
, the modifications are back in the working directory, and you can use the git add
command to add them back to the staging area.
PS:
git diff --cached
can verify the consistency of the contents of the staging area and HEAD.
git reset HEAD
and git restore --staged .
have the same effect; the latter was added after git 2.23+.
22 | How to make the files in the working directory restore to be the same as the staging area?#
Scenario: The working directory has been modified, but you no longer want it and want to restore it to be the same as the staging area.
Command: git checkout <FILENAME>
Let me remind you of this picture:
Process demonstration:
First, use git add
to add the modified readme.md file from the working directory to the staging area:
Observe the results of git diff --cached
before and after the operation, which shows the changes in the differences between the staging area and HEAD, indicating that git add
was successful.
Then, modify the readme.md file again and use git diff
to observe the differences between the working directory and the staging area:
The red box part is the modification this time.
Check the status of the working directory and the staging area using git status
:
The upper part of the figure shows the content to be committed in the staging area; the lower part shows the content to be added to the staging area in the working directory.
You can see that both parts have modifications to readme.md, corresponding to the two modifications just made.
❗️At this point, if you want to restore the content of the readme.md file in the working directory to the state of the staging area, use git checkout readme.md
.
You can see that the readme.md file in the working directory is no longer in the state to be added.
PS:
- Use
git checkout
with caution, as it may lead to files being unrecoverable. - After Git 2.23, use
git switch
andgit restore
to replace the functionality ofgit checkout
:git switch
replaces the functionality of switching branches;git restore
replaces the functionality of restoring files in the working directory. - The effects of
git checkout <FILENAME>
andgit restore <FILENAME>
are the same; the latter was added after git 2.23+.
23 | How to cancel changes to some files in the staging area?#
Command: git reset HEAD [FILENAME]
, similar to section 21, with specific filenames added after the command, and multiple files can also be specified, separated by spaces.
The following example shows the modifications in the staging area being rolled back to the working directory one by one:
If you want to add the modifications in the working directory back to the staging area, use the git add
command.
24 | Eliminate the last few commits#
Command: git reset --hard <HASH_OF_COMMIT>
, which can change the commit pointer of HEAD, and both the staging area and working directory will revert to that commit.
Please see the example below:
Observe the two points before and after git reset --hard
:
1)By using git log
, it can be seen that HEAD's pointer has moved back two commits;
2)By using git diff
, it can be seen that the working directory and staging area have gone from having differences to having no differences.
25 | View the differences of specified files between different commits#
Command: git diff <HASH_OF_COMMIT> <HASH_OF_COMMIT> [-- FILENAME]
Finally, add the specified file; if not added, it will show the differences of all files;
<HASH_OF_COMMIT>
can be directly replaced with branch names, as branch names essentially point to a commit.
PS: Adding --
will make Git clearer about your intentions.
26 | The correct way to delete files#
Command: git rm <FILENAME>
The effect is as follows:
Essentially, it deletes the file and synchronizes this deletion operation to the working directory and staging area, equivalent to:
First, use git reset --hard HEAD
to restore both the working directory and staging area to the state of HEAD;
By using git status
, observe the status of the working directory and staging area before and after the rm
file and git rm
file:
1)The former changed the working directory but did not stage it;
2)The latter synchronized the staging area, and at this point, you can commit this modification.
27 | How to handle an urgent task that interrupts development?#
When an urgent task interrupts, and the current work is only half-finished, what should be done?
git stash
: Moves the contents of the current working directory and staging area to an additional stack, effective only for tracked files.
After completing the urgent task, if you want to restore the half-finished work, first check what has been stashed.
git stash list
: Displays the list of stash records.
Then, restore the most recent stash content to the working directory.
git stash apply
: Restores the top saved record from the stack, and the record will still remain in the list.
git stash pop
: Restores the top saved record from the stack and deletes that record from the list.
- PS: You can also specify a particular record to restore.
Process demonstration:
An urgent task comes in, and first, stash the unfinished content in the staging area.
At this point, a record {0} has been added to the stash record list, and the current working directory and staging area are clean.
After finishing, restore the most recent record from the stash.
You can see that apply
will not clear the stash record, and the restored content is placed in the working directory, while the content that was stashed was from the staging area.
Next, try another way to restore, using pop
and adding the --index
parameter.
You can see that pop
will clear that stash record, and the restored content is placed in the staging area just like when it was stashed; --index
actually means that it will also restore the staging area.
PS:
WIP stands for Work in Progress, indicating that the code in the current working directory is still being written and cannot run independently; it is a half-finished product.
28 | How to specify files that do not need Git management?#
Method: Declare file types or filenames in the .gitignore
file (must be .gitignore
).
Demonstration of the difference between declaring doc/ and doc:
1)doc/: Ignores the folder but does not ignore a file with the same name.
Create a doc folder and add a readhim file inside.
After adding doc/
to the .gitignore
file, Git will ignore tracking of the doc folder.
However, if you change the doc folder to a doc file, Git will not ignore tracking of the doc file.
2)doc: Ignores both the folder and the file with the same name.
For the ignore rule doc, whether it is a folder or a file with the same name, Git will ignore tracking of both.
⚠️:
- Common wildcard
*
to ignore similar files. - If a file has already been tracked, the
.gitignore
file will not take effect.- If you want to ignore some files that have already been committed, you can add the files you want to ignore to the
.gitignore
file and then usegit rm --cached FILENAME
to ignore the files that do not need tracking.
- If you want to ignore some files that have already been committed, you can add the files you want to ignore to the
- When creating a new repository on GitHub, you can choose to add a suitable .gitignore file (very thoughtful ❤️).
PS: For different languages or projects, common .gitignore
files can be referenced from the github/gitignore repository.
29 | How to back up a Git repository locally?#
Related commands: git clone
, git remote
, git push
Common transmission protocols: local protocol, http/https protocol, ssh protocol; the latter two are most commonly used in work.
Transmission protocols can be divided into two categories: dumb protocols and smart protocols; here we take the local protocol as an example:
1)/Path/to/.git; 2)file:///Path/to/.git
The former is a dumb protocol, while the latter is a smart protocol.
So what is the difference between the two when backing up Git?
Compared to dumb protocols, smart protocols have 1) visible transmission progress, and 2) faster transmission speed.
Comparison of the effects of smart and dumb protocols:
By using pwd
, we obtained the repository address used in the previous demonstration: /Users/double/Desktop/test
.
Now, using both protocols, we will back up the repository to another location: the test_remote directory.
Dumb Protocol
⚠️: --bare
means creating a bare repository, which is a repository without a working directory, convenient for use as a server; the backup is the .git folder, so the address must add /.git
; the last ya.git
indicates the repository name.
Smart Protocol
Returning to the test.remote directory, use the smart protocol by adding the file://
prefix.
Comparing the two, you can see the intuitive difference: the dumb protocol does not have a progress bar, while the smart protocol does.
The above demonstrates the process of cloning (clone
) a remote repository to the local; how to push (push
) a local repository to the remote?
Returning to the original repository (where the original repository's role has shifted from remote to local), create a new branch named new
.
At this point, the remote intel.git repository only has three branches:
Add the remote server locally:
git remote add intel file:///Users/double/Desktop/test_remote/intel.git
PS: intel
is the server alias, and the following is the server address, using the smart protocol.
You can check the detailed server information using git remote -v
.
Next, perform the push: git push REMOTE_NAME
command.
⚠️: Directly pushing will result in an error; you need to set the upstream first.
Check the branch situation of the remote intel.git repository again:
You can see that the branch new
has been pushed over!
Having learned this, what are some things you didn't know before? Feel free to share!