preface

This section introduces the branch mapping between local and remote repositories: Git RefSpec. Find out once and for all how the local repository communicates with the remote repository.

A,Git refspec

Refspec stands for Reference Specification. It is a format that git uses to represent the mapping between local and remote branches.

Create two branches develop and test in the local repository outside of the master branch:

Error “Git push” on develop branch

This is because the local branch develop is not connected to any remote branches. Git branch -vv: git branch -vv: git branch -vv

Local remote branch

Before explaining how to set up a remote branch associated with a local branch, let’s introduce the long-awaited local remote branch:

  • gitIn fact, there are three branches: local branch, local remote branch, remote branch;
  • The local remote branch is a mirror image of the remote branch and acts as a bridge between the local and remote repositories.
  • When there is no way to view the remote repository directly, you can observe changes to the remote branch through the local remote branch. Such as local remote branchesorigin/developThat corresponds to the remote branchdevelop.

1. Three-branch relationship

When the local master branch is associated with the remote master branch, check the current branch status:

In the figure, origin/master is the local remote branch, which represents the master branch of the remote warehouse, and this branch is local. Add the master branch of the remote repository and there are three master branches:

In addition, after each branch in the local repository has a remote branch associated with it, the local repository will create the corresponding local remote branch, and their location and relationship are shown in the following figure:

Local remote branch origin/master is the localized form of remote branch master.

Assume that the contents of the remote and local warehouse files are the same, with only two commits, and the states of the three branches are as follows:

Add submit 3rd to the master branch of the local repository

Git dog is an alias for the command: git log –all –decorate –oneline –graph, which will be covered in the next section.

A schematic diagram of the branch is as follows:

The local master branch commits one more time than the local remote branch Origin/Master. This is because the local remote branch exists to keep track of the remote branch, and its orientation is updated only when a pull or push operation is performed. For example, when executing a push command:

  • First, the local remote branch (origin/master) will point to the latest commit from the local master branch (a few steps forward).

  • The local master branch then pushes the file to the remote Master branch. After the push is completed, the status of the three branches is:

Back at the terminal, we push the newly added 3rd submission to the remote branch. If successful, we check the local branch and the local remote branch’s submission history:

As you can see, the local remote branch has been updated to point to the latest commit 3rd, confirming this statement.

Viewing branch associations

You can use the following command to view the association between the local branch and the local remote branch:

git branch -vv
Copy the code

The local master branch is associated with the local remote branch origin/master, indicating that the local master branch has been associated with the remote master branch.

The other two local branches, POP and Develop, do not have local remote branches associated with them, so they are not associated with remote branches.

Simply put: as long as a local branch has a corresponding local remote branch, there is a corresponding local remote branch.

Summary: Origin/Master function: trace remote branches. When you perform a Git push/pull operation, the direction of the branch changes accordingly to keep in sync with the remote repository. For example, when a local repository performs a Git push operation, it not only pushes local changes to a remote repository; It also changes the origin/ Master branch orientation;

2. Field demonstration

This command allows you to view all local branches and their latest commit information:

git branch -av
Copy the code

First, make three commits on the master branch and push it to the remote master branch associated with it. The commit history of each branch is as follows:

The states of the three branches are:

On this basis, do a 4th commit on the master branch and check the status:

The prompt in the figure indicates that the current branch (Master) has committed one time before the Origin/Master branch. To see more clearly, let’s look at the commit history of each local branch:

As you can see from the figure, the Origin/Master branch is indeed one commit behind, indicating that the remote Master branch is one commit behind. At this point, you can use Git push to push the new commit to the remote master branch. In this process, the local remote branch Origin/Master will point to the latest commit 4th. After a successful push, check the commit history of the local branches again:

As you can see, the local remote branch has indeed been updated through git push, pointing to the latest commit 4th. This verifies that git push takes two steps:

  • The localmasterNew commits for branches are pushed to the remote associated with themmasterBranch;
  • Local remote branchorigin/masterPoint to the localmasterThe latest commit for the branch;

Git pull also updates the direction of the local remote branch.

That is, after each push or pull operation, the local branch, local remote branch, and remote branch are synchronized.

When switching to the Origin/Master branch, it looks like this:

Git does not switch the branch directly to Origin/Master, but to the latest commit, a stray commit. Git does not allow us to modify the Origin/Master branch directly, only allowing us to switch to the latest commit.

That is, local remote branches (e.gorigin/master) is read-only and can only be accessed bygitThat explains why it’s used, rightgit branchUnable to view local remote branches.

3. Set the remote branch

Now that you know what a local remote branch is, you can better understand how to establish the connection between the local branch and the remote branch.

1. Set the remote branch with the same name

Upstream branch indicates the upstream branch of the remote repository. The current local develop branch does not have a remote repository corresponding to the Develop branch; To push the Develop branch to a branch of the same name in a remote repository, first create the corresponding remote branch. There are two types and four methods:

  • Type 1: establishing local and remote branch tracing relationships.

    git push --set-upstream origin <branch>
    git push -u origin <branch>
    Copy the code

    With this type of method, you only need to set it up once, after which you can push it using the shorthand git push.

  • Type 2: does not establish local and remote branch tracing relationship.

    git push origin HEAD
    git push origin <branch_name>
    Copy the code

    With this type of method, each push needs to be written in full as described above.

Here are the four methods:

git push --set-upstream origin <branch>

Create a remote branch for the develop branch of the local repository mygit with the following command:

git push --set-upstream origin develop
Copy the code

The develop () command creates a branch develop associated with the local branch in the remote repository and pushes the local Develop file to the remote branch.

Set the upstream branch of local Develop to the Develop branch of the remote repository and synchronize files.

After executing the above command, you will see the following prompt:

Indicates that the local Develop branch has established contact with the remote Develop branch. The origin/develop branch is connected to the local develop branch:

Git push again should not be a problem:

You can see the new remote develop branch on Github:

The master branch in the figure above is created by default when the remote repository is created and is not associated with the local Master branch.

Click branch to see:

The master branch is the default branch and cannot be deleted. The active branch is DEAvelop.

git push -u origin <branch>

Method 2: Switch to the test branch and run the following command to create a remote branch for the test branch of mygit:

git push -u origin test
Copy the code

-u works like –set-upstream to create a new branch in the remote repository and establish a connection with the local branch.

After executing the above command, check the details of the local branch and the corresponding relationship between the branches. You can find that the test branch has established a connection with the remote test branch:

git push origin HEAD

Method 3:

As shown in the figure below, this command successfully sets up the remote Develop branch corresponding to the local Develop branch. But no trace information is displayed, and you can’t use Git push afterwards.

git push origin <branch>

Method 4:

As shown in the figure below, this method is essentially the same as method three, because HEAD points to the current branch. Again, no trace information is displayed, and git push cannot be used later.

Summary: When a local branch has the same name as a remote branch, once the connection between them is manually established. You can then push files from the local branch to the corresponding remote branch using the shorthand git push.

Git push automatically matches a remote branch with a local branch with the same name.

In other cases, the full script is used to push. These conclusions are described in detail in the role of the third point, the -u parameter.

2. Set remote branches with different names

Note the following four methods: Before using each method, switch to the corresponding branch.

git push --set-upstream origin <branch1>:<branch2>

For example, if you are currently in the Develop branch, use the following shorthand command:

 git push --set-upstream origin develop
Copy the code

A remote branch develop with the same name is created. If you use the full version of the command, you can customize the name of the remote branch, such as develop2:

git push --set-upstream origin develop:develop2
Copy the code

After executing the above instructions, the corresponding local remote branch origin/develop2 with a different name was successfully created. Indicates that the local Develop branch has established a relationship with the remote develop2 branch (because the remote branch has a one-to-one correspondence with the local remote branch) :

Looking at the remote repository MY associated with the local repository on Github, you can see that the develop2 branch was created successfully:

You can see the rule that creating a remote branch is accompanied by creating a local remote branch with the same name.

git push -u origin <branch1>:<branch2>

Method 2:

As shown in the figure below, you can also customize the remote branch of the local Develop branch to develop2 using the -u parameter.

git push origin HEAD:<branch>

Method 3:

This method can also be used to successfully set up the remote branch develop2 with different names associated with the local branch:

git push origin <branch1>:<branch2>

This method is essentially the same as method 2, because the HEAD pointer in method 2 points to the current branch, the Develop branch. The process is similar to method 2:

All four methods of setting up remote branches with different names have one thing in common: you can’t use Git push.

Git push can not find the remote branch:

The reason is explained in more detail in the role of the -u parameter in point 3 below.

Since it’s a -u parameter tracking problem, why don’t I just add the -u parameter? That doesn’t work either:

Solution: Each time you push, specify the relationship between the local branch and the remote branch, that is, use the full form of the command above, such as:

git push --set-upstream origin develop:develop2 git push -u origin develop:develop2 git push origin develop:develop2 git  push origin HEAD:develop2Copy the code

After adopting the complete writing method, push was successfully carried out, as shown in the figure below:

Note: While it is possible to customize the names of remote and local remote branches, it is not recommended because of error prone. Therefore, it is recommended that both the local and remote branches use the default name, which is the same as the local branch.

3. Summary

Take the local branch Develop as an example:

  • When using the following shorthand commands, both the remote and local remote branches have the same default name as the local branch:

    git push --set-upstream origin develop
    git push -u origin develop
    Copy the code
  • Using the full form of the following command, you can customize the names of the remote and local remote branches:

git push --set-upstream origin develop:develop2 git push -u origin develop:develop2 git push origin develop:develop2 git  push origin HEAD:develop2Copy the code

Four,git push origin masterwithgit push -u origin masterThe difference between

When the master branch of the local repository is pushed to the master branch of the remote repository for the first time, both the former and the latter can be pushed successfully. The difference is whether the -u parameter is used:

  • Do not use the -u parameter when pushing:

  • Push with -u parameter:

Note that the following prompt message is printed when the -u parameter is used:

Branch 'master' set up to track remote branch 'master' from 'origin'.
Copy the code

Git push means that the local master branch is set to track the remote master branch. For the 2nd to NTH push, just use a shorthand command like git push (of course, the full version is equivalent). Git will automatically match the local master branch with the remote master branch:

When the -u parameter is not used, there is no branch trace information described above. Git push git push git push git push

Error message: the current branch has no corresponding remote branch. In order to push successfully, you must use the complete writing that indicates the corresponding relationship, such as:

git push origin master
Copy the code

This is the difference between pushing without using the -u argument. In addition, according to the above introduction, push can also achieve the effect of -u parameter by using the following command:

git push --set-upstream origin develop
Copy the code

You can also use the short git pull command to push:

If you are careful, you must have noticed that these are only local branches with the same name as remote branches. Do the above two methods work with different names?

First, verify method I: -u parameter:

When setting up remote branches with different names, be careful to write them in the full form :pop :pop2

As you can see, the -u parameter sets the trace relationship even if you create remote branches with different names. However, git push doesn’t work very well:

As with the -u parameter, the corresponding remote branch cannot be found, and the full form specifying the corresponding relationship should be used, such as:

git push origin pop:pop2
Copy the code

“–set-upstream:

Also, use the full script when setting the branch correspondence. As you can see, this method also sets the trace relationship. Oddly enough, git push doesn’t work either:

Also cannot find the corresponding remote branch, need to use the full writing of the corresponding relationship, such as:

git push origin bob:bob2
Copy the code

So the conclusion can be drawn:

  • Local/remote branches with the same name:

    • -uParameter is used to set the tracing relationship between the local branch and the remote branch. After setting the tracing relationship, the subsequent push can be abbreviatedgit push.gitInternal will automatically match;
    • --set-upstreamParameters and-uParameter effect is the same;
  • Local/remote branches with different names:

    • --set-upstreamParameters and-uParameters can still set the tracing relationship of branches, however, subsequent pushes cannot be abbreviatedgit push, can only use the full writing of the specified branch correspondence;

Summary: It is highly recommended that all local branches have the same name as the corresponding remote branch and be used for the first time--set-upstreamor-uParameter sets up the branch trace relationship, after which you can use abbreviationsgit pushPush!

Five,git push -f

The command is written as follows:

git push -f origin master
Copy the code

Forcibly push: directly skip the link of merging with the master branch of the remote warehouse, forcibly overwrite the content of the master branch of the remote warehouse, that is, take the content of the local master branch as the standard. This command should be used with caution as it overwrites files pushed by others on the master branch of the remote repository (a week’s worth of work is lost).

1. Application scenarios

  • When the remote repository’s historical commit records get too messy and you want to reorganize them. ** Note: ** must negotiate with others before forcibly overwriting remote branches with local branches.
  • When only one person is developing, the code is local. To avoid cumbersome merge when pushing, you can use-fForced push, directly overwriting the content on the remote branch;

There are two ways to write it:

  • The first method: When the tracing relationship between the local branch and the remote branch has been set using the -u parameter, the following method is used:

    git push -f
    Copy the code

  • Second: no tracking relationship has been set, adopt:

    git push -u origin master -f
    Copy the code

2. Preventive measures

GithubProvides the corresponding branch protection mechanism, can be inSettingsOptions to set:

Github protects branches by default:

3. Remedies

Git push -f: git push -f: git push -f: Git push -f: Git push

6. Set the local branch corresponding to the remote branch

Create an empty local repository mygit and set origin to M3Y with the following command:

git remote add origin [email protected]:AhuntSun/M3Y.git
Copy the code

At this time, the status of the two warehouses is:

Since myGit is an empty repository and the remote repository M3Y does not have any common commit history, different source conflicts occur when git pull is executed as shown in the following figure (described in detail in the previous section) :


Although the Git pull operation failed, it was also successful in pulling down the branch of the remote repository M3Y. Git branch-vv does not have a local branch associated with the remote branch.

How do I create a local branch corresponding to these two local remote branches? This can be done in the following two ways:

1.git checkout -b <branch> origin/<branch>

For example, you can run the following command to set the tracing relationship between the local remote origin/master branch and the local master branch:

git checkout -b master origin/master
Copy the code

If the master branch has not been created, run the following command to create the develop branch, switch to the Develop branch, and set the origin/develop tracing relationship with the Develop branch:

git checkout -b develop origin/develop
Copy the code

Git push > git push > git push > Git push > Git push

2.git checkout --track origin/<branch>

Create an empty local repository mygit2 and set origin to M3Y’s address. Then perform git pull on mygit2 to pull two branches from remote M3Y:

As last time, the two local remote branches that were pulled locally did not establish a trace relationship with any local branches. This time you can take another approach:

git checkout --track origin/test
Copy the code

Create and switch to the Develop branch and set the trace relationship between that branch and the Origin/Develop branch:

This method is a special case of method one, because it does not specify the name of the local branch being created, so it defaults to the same name as the remote branch develop.

If you want to set up a local develop2 branch (different name) to establish a trace relationship with the local remote branch Origin/Test, you should use the first method.

7. Remote branch information

You can go to the.git directory and view the file that stores the remote branch information:

1. Check theconfigfile

Open the file using the Vim editor to see information about the remote branch:

You can see that there are two pieces of information in the remote column, the first is the URL of the remote repository and the second is the fetch information, which are particularly important:

  • refs/heads/*Representing the remote repositoryrefs/headsAll references to directories are written locallyrefs/remotes/originDirectory;
  • One of the+The number is optional and is added to indicate whether or not automatic merging is possible, that is, whether or notFast ForwardPull all files from the remote warehouse to the local.
  • And do not add+If noFast ForwardThe way is not to pull. Usually it’s plus+Number, first pull the file to the local, notFast ForwardWay to manually merge;

2. Check therefsfile

The refs folder holds the refSpec files and maintains three directories:

  • The first directory heads: stores branch information for the local repository:

    You can view one of the branches:

    Is an SHA1 value, indicating that the branch is a pointer to the current commit.

  • The second directory is remotes, which holds the remote branch information and files in the remote repository.

    As you can see from the figure above, the remote branch only has master, not develop (because it was removed earlier). And they are also essentially a SHA1 value representing the submitted value:

    Git will fetch all references to refs/ Heads and write them to the local refs/ Remotes/Origin directory. So, you can view the historical commit record on the master branch of the remote warehouse when the remote warehouse was last accessed by the local branch (such as Origin /master) :

    
    // Complete
    git log refs/remotes/origin/master
    // Further shorthand
    git log remotes/origin/master
    // Continue the shorthand
    git log origin/master
    Copy the code

    Both ellipses will eventually be converted to the full form:

  • The third directory tags: store tag information, also an SHA1 value:

    Details will be covered in the next section.

Delete the remote branch

As shown in the figure below, the remote repository has three branches: Master, Develop, and Test:

You can remove the local Develop branch with the following command:

git branch -d develop
Copy the code

So how do you remove remote branches?

Git push git push git push

git push origin srcBranch:destBranch
Copy the code
  • srcBranchRepresents a local branch,destBranchRepresents the corresponding remote branch;
  • Push a local branch to a remote branch. The two branches can be different.
  • It can be used directlygit pushBecause we set the name of the local branch and the name of the remote branchThe sameAnd set up the connection manually, sogitAutomatic recognition;

With this in mind, it is easy to understand the following two ways to remove remote branches:

1.git push origin :destBranch

Push an empty branch to a remote branch so that the remote branch can be deleted. For example, delete the local branch develop’s remote branch:

git push origin :develop
Copy the code

You can see that the remote develop branch and its corresponding local remote origin/ Develop branch were successfully removed.

Note: You don’t need to switch to local develop, where you need to remove remote branches, to execute the above instructions. That is, you can delete remote branches corresponding to any local branch on any local branch.

2.git push origin --delete destBranch

You can also use a more intuitive –delete argument, such as deleting the remote branch develop:

 git push origin --delete develop
Copy the code

These two methods are equivalent and can be selected according to your needs.

3.git remote prune origin

This method is used to delete the local remote branch corresponding to the invalid remote branch in the following situations:

Mygit shares a remote repository with three branches with mygit2 as shown:

Select origin/develop from mygit2 where origin/develop is the local branch of remote develop;

Then view the remote branch details in mygit:

The local remote develop branch is stale or stale, and the local remote develop branch is stale or stale.

git remote prune origin
Copy the code

(Prune: clipped) Remove this invalid local remote branch from mygit:

The origin/develop branch has been deleted from mygit:

Note: Generally, local remote branches are protected and cannot be deleted at will.

Rename branches

1. Local branch

To rename the local branch dev to develop, run the following command:

git branch -m dev develop
Copy the code

2. Remote branch

You cannot rename a remote branch directly. You can delete the original remote branch and create a remote branch corresponding to the rename branch.

// Delete the remote branch dev
git push origin :dev
// Create a remote branch corresponding to the rename develop branch
git push -u origin develop
Copy the code

This indirectly completes the renaming of the remote branch.