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, switch branches first using
git checkout <BRANCH_NAME>
. - To delete a remote branch:
git push <REMOTE> --delete <BRANCH_NAME>
- Synchronize the branch list with
git fetch -p / --prune
, at which point the remote deleted branches will no longer be displayed.
- Synchronize the branch list with
15 | How to modify the message of the latest commit?#
Enter git commit --amend
, a text editor will pop up, modify the new commit message as shown in the red box:
After entering :wq
to save and exit, the terminal displays 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 commits 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, -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 3rd 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
), and an editing interface will pop up:
The order of commits is reversed; from the Commands section, you can see many usages.
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 pops 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
:
You can see that the message of the 3rd commit has been successfully modified, and the hash values of the first three commits have changed, except for the message of the 3rd commit, which has not changed; other information has not changed either, which can be verified.
⚠️:
- 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 focus on its similarities and differences withmerge
, refer to:- Git Branch - Rebase——Official
- The Correct Way to Use 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 3 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
), and an editing interface will pop up:
The 3 commits to be merged are shown in the red box above, in the reverse order of what is displayed by git log
.
Using the squash / s
command from Commands, we can merge a commit into the previous commit, modify as follows:
After saving and exiting with :wq
, a new editing interface pops up:
Add a second line as the message for merging the 3 commits, keep the messages of each commit below, and 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; you can see that the hash values of the 2 commits have changed because the commit message or the pointer of the parent commit has 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:
- You can see 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, and a familiar window pops up:
Adjust the positions of the commits to be merged and use the s
command, modify 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: resolving the conflict.
PS: You can also use git status
to view the current suggested operations:
Next, check the readme file to resolve the conflicts inside, simply delete the code at the red box position:
Then run git add readme
to add the modification record.
Then, run git rebase --continue
as prompted, an editing box will pop up, enter the message, and :wq
to save and exit (you may need to resolve conflicts again, just repeat the above steps).
Finally, check the version history with git log
:
You can see: 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 image:
- 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:
You can see that two lines of text have been added; once confirmed to meet 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 the 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
, it will restore all files to be consistent with HEAD
.
You can observe the changes before and after reset
using git status
, see the image below:
After reset
, the modified operations are moved back to 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 between 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 it is no longer needed, and you want to restore it to be the same as the staging area.
Command: git checkout <FILENAME>
.
Let me remind you of this image:
Process demonstration:
First, use git add
to add the modified readme.md file from the working directory to the staging area:
Observe the result of git diff --cached
before and after the operation, that is, the change in the difference between the staging area and HEAD, confirming that git add
was successful.
Then, modify the readme.md file again and observe the differences between the working directory and the staging area using git diff
:
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 image 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 made earlier.
❗️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. git checkout <FILENAME>
andgit restore <FILENAME>
have the same effect; 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 the addition of specific filenames after the command, and multiple files can also be specified, separated by spaces.
The following example shows the modifications in the staging area being reverted 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 HEAD's commit pointer, 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
:
-
You can see from
git log
that HEAD's pointer has moved back two commits; -
You can see from
git diff
that the working directory and staging area went 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 the branch name, as the branch name essentially points to a commit.
PS: Adding --
makes Git clearer about your intention.
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;
Then observe the status of the working directory and staging area before and after rm
and git rm
:
-
The former changed the working directory but did not stage it;
-
The latter synchronized the staging area, and at this point, you can commit this modification.
27 | How to handle an urgent task that interrupts ongoing development?#
When an urgent task interrupts ongoing work, what should you do?
git stash
: Moves the current working directory and staging area contents to an additional stack, effective only for tracked files.
After completing the urgent task, to restore the previous half-finished work, first check what has been stashed.
git stash list
: Displays the stash record list.
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 remains 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 came up, so 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
does not clear the stash record, and the restored content is placed in the working directory, while the previously stashed content was from the staging area.
Next, try another way to restore using pop
and adding the --index
parameter.
You can see that pop
clears the stash record, and the restored content is placed in the staging area, just like when it was stashed; --index
means it will also restore the staging area.
PS:
WIP stands for Work in Progress, indicating that the code currently in the working directory is 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 the file types or filenames in the .gitignore
file (it 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 the doc folder.
However, if you change the doc folder to a doc file, Git will not ignore tracking the doc file.
2)doc: Ignores both the folder and the file with the same name.
For the ignore rule doc, regardless of whether it is a folder or a file with the same name, Git will ignore tracking it.
⚠️:
- 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 to be tracked.
- 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?
Smart protocols, compared to dumb protocols, 1) have visible transfer progress, 2) and transfer faster.
Comparison of the effects of smart and dumb protocols:
Using pwd
, we obtained the repository address used in the previous demonstration: /Users/double/Desktop/test
.
Now, back up the repository to another location: the test_remote directory using both protocols.
Dumb Protocol
⚠️: --bare
means creating a bare repository, i.e., a repository without a working directory, which is convenient as a server; the backup is the .git folder, so the address must add /.git
; the final ya.git
indicates the repository name.
Smart Protocol
Returning to the test.remote directory, use the smart protocol by adding the file://
prefix.
The comparison shows an intuitive difference: the dumb protocol does not have a progress bar, while the smart protocol has a progress bar.
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 shifts from remote to local), create a new branch named new
.
At this point, the remote intel.git repository only has 3 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 view detailed server information using git remote -v
.
Next, perform the push: git push REMOTE_NAME
command.
⚠️: Directly pushing will report 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!