[Git Basics] Commonly used git commands (4)

1. Handling emergencies

1.1 Temporary changes

In such a situation, you are focusing on developing a certain feature or refactoring (FT-12345 branch), but suddenly a BUG pops up online, you need to solve the BUG, ​​but what should you do with the current modification? okay? If it is submitted, it will produce a meaningless commit. Then you can use git stash at this time. Here are the steps to use:

  1. First, make sure you are on the branch that needs to be staged (eg: FT-12345). You can view the current branch with the following command:

    git branch
    

    If you need to switch branches, use:

    git checkout FT-12345
    
  2. Use git stashthe command to save your changes to a new repository. You can add an optional descriptive message to make it easier to find and apply this store later:

    git stash save "Work in progress on FT-12345"
    

    This will save your changes to a new repository and restore the workspace to the state of the last commit.

  3. Now you are free to switch to the branch that needs to fix the bug, for example:

    git checkout master
    

    or:

    git checkout hotfix-branch
    
  4. After switching to the correct branch, make the required bug fixes and commit the changes.

  5. Once the bugfix is ​​complete, you can switch back to the original branch (eg: FT-12345):

    git checkout FT-12345
    
  6. Next, use git stash listthe command to view all buckets. You should see output similar to this:

    stash@{
          
          0}: On FT-12345: Work in progress on FT-12345
    
  7. To apply staged changes back to the current branch, use git stash applythe command with a reference to the repository:

    git stash apply stash@{
          
          0}
    

    This will apply your previously staged changes back to the workspace.

  8. If you want to remove an applied stash from the stashes list, you can use git stash dropthe command :

    git stash drop stash@{
          
          0}
    

This way, you can safely save your current branch's changes while you're working on an urgent bug fix, and then restore those changes when you're done working on the bug.

But if you just need to stage the last modification and switch back later, just use git stashand git stash pop:

  • git stashUse staged changes before switching to other branches
  • git stash popUse revert-modification after the modification is complete and switch back to the branch that worked before

1.2 Some commands of git stash

  1. git stash save [<message>]: Save the changes in the current workspace to a new repository and revert to the state of the last commit. You can provide an optional descriptive message to easily distinguish between different stores.

    git stash save "Work in progress"
    
  2. git stash list: List all buckets. The output is similar to:

    stash@{
          
          0}: On branch-name: Work in progress
    stash@{
          
          1}: On another-branch: Another work in progress
    
  3. git stash apply [<stash>]: Apply the specified bucket to the current workspace. If no stash is specified, the closest stash (stash@{0}) is used by default.

    git stash apply stash@{
          
          0}
    
  4. git stash branch <branch-name> [<stash>]: Create a new branch and apply the specified bucket to the new branch. If no bucket is specified, the nearest bucket is used by default.

    git stash branch new-feature-branch stash@{
          
          1}
    
  5. git stash pop [<stash>]: Like git stash apply, but after a store is applied, it is removed from the store list. If no bucket is specified, the nearest bucket is used by default.

    git stash pop stash@{
          
          0}
    
  6. git stash drop [<stash>]: Delete the specified storage area from the storage list. If no bucket is specified, the nearest bucket is deleted by default.

    git stash drop stash@{
          
          1}
    
  7. git stash clear: Delete all storage areas.

    git stash clear
    
  8. git stash push [-m|--message <message>]: This is git stash savean alternative command for . Git 2.13.2 and later is recommended git stash push. It saves the current workspace's modifications to a new repository and reverts to the state of the last commit. You can provide an optional descriptive message to easily distinguish between different stores.

    git stash push -m "Work in progress"
    

2. Specify files that do not need git management

2.1 Specify files that do not need git management

When using Git for version control, programmers of programming languages ​​​​such as Java and C/C++ may encounter a problem: when executing git add .commands such as , the intermediate files generated by compilation (such as .class, .obj, .o, etc.) will be submitted to the repository. To avoid this, Git provides a file called .gitignore to define rules that specify which files should not be submitted to the Git repository.

.gitignore files can be committed to remote repositories so that all developers can share these rules. In the .gitignore file, each line defines an ignore rule, for example:

*.[oa]
*~

The first line means to ignore all files ending with .o or .a, and the second line means to ignore all files ending with "~".

When using .gitignore, generally follow the following rules:

  1. Ignore files automatically generated by the operating system, such as thumbnails, etc.;
  2. Ignore intermediate files, executables, etc. generated by compilation. In other words, if a file is automatically generated from another file, then the automatically generated file does not need to be put into the repository. For example, the .class file generated by Java compilation, or the .obj file of C++;
  3. Ignore configuration files that contain sensitive information, such as configuration files that store passwords or log files.

By following these rules, we can ensure that only the source code and necessary configuration files are included in the Git repository, keeping the repository clean and safe.

2.2 Rules of .gitignore

  1. Empty lines : Empty lines are ignored and can be used to separate different rule groups.

  2. Comments : Lines starting with a pound sign (#) will be treated as comments and will be ignored by Git.

    example:

    # 这是一个注释
    
  3. Wildcards : You can use wildcards such as asterisk (*), question mark (?), and square brackets ([]) for pattern matching.

    • Asterisk (*) : matches any character of any length.
      example:
    *.log  # 忽略所有.log文件
    
    • Question mark (?) : Matches any single character.
      example:
    ?.txt  # 忽略所有单个字符加.txt后缀的文件,如a.txt,但不包括ab.txt
    
    • Square brackets ([]) : Match any single character within the square brackets.
      example:
    [abc].txt  # 忽略a.txt、b.txt、c.txt
    
  4. Slash (/) : Used to specify a directory.

    • Using a slash at the beginning of a rule indicates that the rule applies only to the current directory.
      example:
    /debug.log  # 仅忽略当前目录下的debug.log文件
    
    • Use a slash at the end of the rule to match only directories, not files or symbolic links.
      example:
    tmp/  # 忽略所有名为tmp的目录,但不忽略tmp文件或tmp符号链接
    
  5. Exclamation point (!) : Used to negate a rule, indicating that files or directories matching the rule are not ignored.

    example:

    *.log      # 忽略所有.log文件
    !important.log  # 但不忽略important.log文件
    
  6. Double asterisk (**) : Used to match any number of directory levels.

    example:

    **/debug.log  # 忽略所有目录下的debug.log文件,包括子目录
    
  7. Combination rules : Multiple rules can be combined to meet complex requirements.

    example:

    # 忽略所有.txt文件,但不忽略doc/目录下的.txt文件
    *.txt
    !/doc/*.txt
    /doc/**/*.txt
    

After understanding these rules, you can create a .gitignore file that suits your project needs, and specifically ignore files and directories that do not need to be included in version control.

Here is another URL to automatically generate .gitignore files: https://www.toptal.com/developers/gitignore

3. How to resolve dependencies between projects

3.1 How to use git to handle dependencies between projects

In the product development process, we often encounter situations where the product architecture is divided into multiple modules so that different teams can develop different modules. For example, a source srcdirectory might contain the following modules:

src
 |------- buffer
 |------- f-threadpool
 |------- iniconfig
 |------- intf
 |------- store
 |------- router

It may even depend on third-party projects. To manage these dependencies, we can use Git's submodule feature. Submodules allow a parent project to contain many independent Git subprojects. These sub-projects can be submitted, pushed, pulled, etc. independently, and the commits in the parent project will not affect the sub-projects.

Using submodules has the following advantages:

  1. Separate submodules as a Git project, they can be developed independently, and errors in submodules will not affect the parent project. This helps keep projects isolated and reduces coupling between projects.

  2. The team can work in modules on different Git projects, reducing the dependency on code submission, thereby reducing the conflict and complexity caused by update operations.

By using Git submodules, we can better manage the dependencies between projects, realize modular development, and improve the efficiency of team collaboration.

3.2 How to use submodules

  1. add submodule

    To add a repository as a submodule to the current project, use the following command:

    git submodule add <repository_url> <path_to_submodule>
    

    where <repository_url>is the URL of the submodule repository and <path_to_submodule>is the path of the submodule in the main project.

    For example, we have a main project my_projectand now we want to add a my_librarysubmodule called:

    git submodule add https://github.com/username/my_library.git libs/my_library
    

    This will libs/my_libraryadd my_librarysubmodules under the directory.

  2. Initialize and update submodules

    After adding a submodule, it needs to be initialized and updated. Do this with the following commands:

    git submodule init
    git submodule update
    

    This will check out the submodule's code. You can also use --recursiveoptions to initialize and update all submodules and their submodules at the same time:

    git submodule update --init --recursive
    
  3. Update submodules when main project is pulled

    To ensure that submodules are also updated when pulling the main project from a remote repository, the following command can be used:

    git pull --recurse-submodules
    
  4. Make changes in submodules

    To make changes in a submodule, first go into the submodule directory, then make changes, commit and push as you would a normal Git repository:

    cd libs/my_library
    # 对子模块进行更改
    git add .
    git commit -m "Update submodule"
    git push
    
  5. Update references to submodules in the main project

    After making changes in the submodule and pushing, you need to update the references of the submodule in the main project. Back in the main project directory, use the following command:

    cd ../..
    git add libs/my_library
    git commit -m "Update submodule reference"
    git push
    

    This will update the submodule's reference in the main project to point to the submodule's latest commit.

  6. delete submodule

    To remove a submodule from a project, follow these steps:

    1. Delete .gitmodulesthe associated submodule entry in the file.
    2. Delete .git/configthe associated submodule entry in the file.
    3. Delete the submodule's directory in the file system.

    Then commit these changes:

    git add .gitmodules
    git rm --cached <path_to_submodule>
    git commit -m "Remove submodule"
    git push
    

    The submodule has now been successfully removed.

3.3 How to clone submodules

When cloning a project that contains submodules, Git by default clones the main project but not the contents of the submodules. In order to clone the main project and submodules at the same time, the following method can be used:

--recurse-submodulesMethod 1: Add options when cloning

--recurse-submodulesClone the main project and all its submodules with options:

git clone --recurse-submodules <repository_url>

This will clone the main project and all its submodules, and automatically initialize and update the submodules.

Method 2: Manually initialize and update submodules after cloning

If you have cloned the main project, but not the submodules, you can manually initialize and update the submodules with the following commands:

git submodule init
git submodule update

If there are also nested submodules within the submodule, you can use --recursivethe option to initialize and update all submodules and their submodules at the same time:

git submodule update --init --recursive

3.4 Pitfalls and challenges of submodule

  • Complexity of submodules: The use and management of submodules is more complex than normal Git repositories, requiring additional commands and operations. Especially for team members who are not familiar with submodules, it may encounter difficulties and challenges.

  • Version references for submodules: A submodule is just a reference to a specific commit in the main project, rather than tracking the latest changes to the submodule in real time. This can cause problems when updating submodules, requiring manual updates of submodule references in the main project.

  • Forgetting to initialize and update submodules: When cloning the main project, it is possible to forget to --recurse-submodulesinitialize and update submodules using options or manually. This can lead to missing submodule code, throwing build or runtime errors.

  • Separation of submodule and main project: The submodule is an independent Git warehouse, which needs to be submitted, pulled and pushed separately. This can lead to confusion and mishandling among team members when managing submodules and the main project.

  • Permissions and access control: Submodules may be located in different Git repositories with different permissions and access controls. When configuring submodules, you need to ensure that all team members have appropriate access rights to avoid errors caused by permission issues.

  • Deleting and moving submodules: Deleting or moving submodules involves multiple steps and is error-prone. If done incorrectly, it can lead to incorrect or inconsistent references in the Git repository.

3.4 How to update the content of submodule

When the remote warehouse of the submodule is updated, the content of the submodule needs to be updated in the main project. The steps to update the content of a submodule are given below:

  1. Enter the submodule directory: First, navigate to the submodule's directory:

    cd <path_to_submodule>
    
  2. Pull the latest changes of the submodule: Use git fetchthe command to pull the latest changes of the submodule from the remote repository:

    git fetch
    

    You can also choose to pull updates from specific branches, for example:

    git fetch origin master
    
  3. Checkout an update of a submodule: Use git checkoutthe command to update a submodule to the latest commit. If you want to update to the latest version of the remote branch, you can do this:

    git checkout origin/master
    

    If you want to update to a specific commit, you can do it like this:

    git checkout <commit_sha>
    
  4. Return to the main project directory: After updating the submodules, return to the main project directory:

    cd ..
    
  5. Update the submodule references in the main project: Use the git addand git commitcommands to add updates to the submodules to the main project:

    git add <path_to_submodule>
    git commit -m "Update submodule to the latest version"
    
  6. Push the changes of the main project: Push the changes of the main project to the remote repository:

    git push
    

Now, the submodule has been updated to the latest version, and the submodule reference in the main project has also been updated. Note that these steps require switching between the main project and the submodules , since they are separate Git repositories.

3.5 How to synchronize submodule updates

When the remote repository of the submodule is updated, you need to synchronize the content of the submodule in the main project. Here are the steps to synchronize submodule updates:

  1. Pull the latest changes to the main project: First, make sure you've pulled the latest changes to the main project:

    git pull
    
  2. Initialize the submodule (if not already initialized): If the submodule has not been initialized, use the following command to initialize it:

    git submodule init
    
  3. Update submodule content: Use the following command to update the submodule content:

    git submodule update
    

    This will update the submodule to the specific commit referenced in the main project.

    If there are also nested submodules within the submodule, you can use --recursivethe option to initialize and update all submodules and their submodules at the same time:

    git submodule update --init --recursive
    
  4. Pull the latest changes of the submodule (optional): If you want to update the submodule to the latest changes of the remote repository, not just the specific commit referenced by the main project, you can do it in the submodule directory git pull:

    cd <path_to_submodule>
    git pull
    cd ..
    

    Note that if you do this step, you need to make sure the submodule references in the main project are also updated to the latest changes to avoid inconsistent references.

Through the above steps, you can synchronize the updates of submodules in the main project. This will ensure that the submodule contents are consistent with the commits referenced by the main project.

3.6 Working in submodules

When developing and modifying in submodules, you can think of submodules as an independent Git repository. Here are the basic steps for working in a submodule:

  1. Navigate to the submodule directory: First, enter the submodule's directory:

    cd <path_to_submodule>
    
  2. Pull the latest changes from the submodule: To make sure you're working on the latest version of the submodule, pull the latest changes from the remote repository:

    git fetch
    git checkout <branch_name>
    git pull
    
  3. Create a new branch (optional): If you need to work on a new branch, you can create a new branch:

    git checkout -b <new_branch_name>
    
  4. Make Changes: Make the desired changes and modifications in the submodule.

  5. Commit changes: Add the changes to the staging area and commit them:

    git add .
    git commit -m "Your commit message"
    
  6. Push changes: Push the changes to the remote repository:

    git push
    
  7. Go back to the main project directory: Once you're done making changes to the submodules, go back to the main project directory:

    cd ..
    
  8. Update the submodule references in the main project: Add the submodule's changes to the main project, and commit the updated references:

    git add <path_to_submodule>
    git commit -m "Update submodule reference"
    
  9. Push the changes of the main project: Push the changes of the main project to the remote repository:

    git push
    

With these steps, work and develop in the submodule just like in any other standalone Git repository. Just make sure to properly update and commit the submodule references in the main project when you're done making changes to the submodule.

3.7 Delete submodule

If you want to delete a submodule from a Git repository, you need to complete the following steps:

  1. Delete submodule directory: Delete the submodule directory and its contents:

    git rm --cached <path_to_submodule>
    

    This will remove the submodule from the staging area, but not the submodule's physical files.

  2. Delete submodule's physical files: Delete submodule's physical files and directories:

    rm -rf <path_to_submodule>
    
  3. Modify .gitmodulesfile: Edit .gitmodulesthe file, removing entries related to submodules. This might resemble the following:

    [submodule "path_to_submodule"]
        path = path_to_submodule
        url = https://github.com/user/repo.git
    

    Delete the entire entry, then save and close the file.

  4. Commit changes: Add these changes to the staging area and commit:

    git add .gitmodules
    git commit -m "Remove submodule"
    
  5. Remove submodule configuration: .git/configRemove submodule-related configuration from the file. Edit .git/configthe file and find the section related to submodules, similar to the following:

    [submodule "path_to_submodule"]
        url = https://github.com/user/repo.git
    

    Delete the entire section, then save and close the file.

  6. Clear submodule cache: Run the following command to remove submodule related information from Git cache:

    git rm --cached <path_to_submodule>
    
  7. Push changes: Push the changes to the remote repository:

    git push
    

The submodule is now completely removed from the Git repository. Note that these steps involve the modification of multiple files, so care needs to be taken to avoid causing problems.

4. How to backup git repository

For disaster recovery, many companies will back up the git warehouse. The following are some basic steps:
insert image description here

  1. Set the password-free login method of ssh:
    ssh-kengen –t rsa  # 以rsa算法生成密钥对
    vim ~/.ssh/id_rsa.pub # 把id_rsa.pub的内容拷贝后放在git仓库的/root/.ssh/authorized_keys里
    chmod 400 /root/.ssh/authorized_keys   # 在git服务器上设置文件的权限为400
    
  2. Write the following script: We use the ssh protocol git cloneto --mirrorcopy the image (it cannot be omitted, because the git warehouse has a lot of branch and tag information)
giturl="[email protected]:/srv/"
# reslist=("nginx-docs.git")
reslist=$(ssh [email protected] "cd /srv ; ls")
for res in ${reslist[@]};
do
	cd ${res}
	#echo ssh://${giturl}${res}
	git clone --mirror ssh://${giturl}${res}
done
  1. Add timing tasks through crontab:
crontab –e   # 在定时任务中添加: 0 0 * * * sh /srv/backup_remote_git.sh,然后保存
systemctl restart cron  # 重启cron服务,如果在centos是systemctl restart crond

Guess you like

Origin blog.csdn.net/weixin_52665939/article/details/130515971