Git branch management
Almost every version control system supports branches in some form. Using branches means that you can separate from the main line of development and continue working without affecting the main line.
Some people call Git's branch model a nirvana feature, and it is precisely because of it that distinguishes Git from the family of version control systems.
Create branch command:
git branch (branchname)
Switch branch command:
git checkout (branchname)
Create a branch and switch to the newly created branch
git checkout -b (branchname)
[root@jinkai newfile]# git branch
* main
[root@jinkai newfile]# git branch admin
[root@jinkai newfile]# git branch
admin
* main
[root@jinkai newfile]# git checkout admin
Switch to branch'admin'
[root@jinkai newfile]# git branch
* admin
main
When you switch branches, Git will replace the contents of your working directory with the last committed snapshot of that branch, so multiple branches do not need multiple directories.
But when git add is added to the library, the content of each branch is separate, as follows: 1.txt is added to the admin branch as follows, switch back to the main branch to check that there is no
[root@jinkai newfile]# git checkout admin
Switch to branch'admin'
[root@jinkai newfile]# echo 11111 > 1.txt
[root@jinkai newfile]# git add 1.txt
[root@jinkai newfile]# git commit -m "touch 1.txt"
[admin 13f3b30] touch 1.txt
1 file changed, 1 insertion(+)
create mode 100644 1.txt
[root @ jinkai newfile] # ls
1.txt a.txt README.md
[root@jinkai newfile]# git checkout main
Switch to branch'main'
[root @ jinkai newfile] # ls
a.txt README.md
Merger of branches:
Before merging branches, switch to the target branch and merge the admin branch into main
[root@jinkai newfile]# git checkout main
Already located in'main'
[root@jinkai newfile]# git merge admin
Update 957bc21..13f3b30
Fast-forward
1.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 1.txt
Conflicts arising from the merger:
If both the admin branch and the main branch have edited a.txt, a conflict will be prompted when merging, and the conflict needs to be resolved before the merging can continue.
The way to resolve the conflict is to edit a.txt under the main branch and change it to the content of a.txt in the admin branch. Then submit a.txt, and then merge the admin branch.
[root@jinkai newfile]# git merge admin
Automatically merge a.txt
Conflict (content): merge conflict in a.txt
The automatic merge fails, correct the conflict and submit the corrected result.
[root@jinkai newfile]# cat a.txt
yyyy
<<<<<<< HEAD
mainmainmainmain
=======
mainmainmain
adminadminadmin
\>>>>>>> admin
[root@jinkai newfile]# vim a.txt
[root@jinkai newfile]# git add a.txt
[root@jinkai newfile]# git commit -m "main file a.txt"
[main 7baca4e] main file a.txt
[root@jinkai newfile]# git merge admin
Already up-to-date.
But there is a problem. What if the content of the main branch is what we want? You can edit the content of a.txt, change it to what you want, and then submit it. Switch to the admin branch, and then merge the main branch to the admin branch (reverse merge).
[root@jinkai newfile]# git checkout admin
Switch to branch'admin'
[root@jinkai newfile]# git merge main
Update 3445592..f2828c2
Fast-forward
a.txt | 1 -
1 file changed, 1 deletion(-)
[root@jinkai newfile]# cat a.txt
yyyy
mainmainmain
The principle of merging branches is to merge the latest branch into the old branch. In other words, the branch name following merge must be the latest branch.
Delete branch:
git branch -d admin
If the branch is not merged, it will prompt before deleting, then do not merge and force deletion
git branch -D admin
To restore a deleted branch:
Git will be responsible for branch management, so when we delete a branch, Git only deletes the pointer to the relevant commit, but the commit object will still remain in the repository.
Therefore, if we know the hash value when the branch is deleted, we can restore a deleted branch. Recover a branch when the hash value of the commit is known:
git branch <branch_name> <hash_val>
If we don't know the hash value of the branch we want to restore, we can use the reflog command to find it out. Such as:
[root@jinkai newfile]# git branch -d admin
The branch admin (formerly ca5f319) has been deleted.
[root@jinkai newfile]# git branch admin HEAD@{0}
reflog ** command **:
Shows the commits of the entire local repository, including the commits of all branches, and even the commits that have been revoked.
As long as the HEAD changes, it will be visible in the reflog.
At this time, the restoration branch a_branch branch is as follows:
git branch admin HEAD@{0}
Principles of using branches:
For branch applications, I suggest you follow this principle:
The main branch is very important. Use this branch for online code release. We usually don't develop code on this branch.
Create a dev branch, dedicated to development, and merge the dev branch into main only before publishing it online.
Developers should branch into a personal branch on the basis of dev, develop code in the personal branch (on their own pc), and then merge into the dev branch.
The command for the dev branch to merge the bob branch is:
[root@jinkai newfile]# git checkout dev
Switch to branch'dev'
[root@jinkai newfile]# git merge bob
Already up-to-date.
[root@jinkai newfile]# git checkout main
Switch to branch'main'
[root@jinkai newfile]# git merge dev
Already up-to-date.
Remote branch management
If the newly created local branch is not pushed to the remote, it will be invisible to others
View remote branches:
git ls-remote origin
[root@jinkai newfile]# git ls-remote origin
f2828c2b54dfd986da7a8798733b19bf82793145 HEAD
f2828c2b54dfd986da7a8798733b19bf82793145 refs/heads/main
There are two cases for git push branches
When the local branch and the remote branch are the same
git push will push the changes of all local branches to the remote together. If you want to push only one branch, use git push origin branch-name
[root@jinkai newfile]# git push origin admin
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'admin' on GitHub by visiting:
remote: https://github.com/jinkai-linux/newfile/pull/new/admin
remote:
To https://github.com/jinkai-linux/newfile.git
* [new branch] admin -> admin
When there are more local branches than remote branches, by default git push only pushes local and remote branches. When you want to push the extra local branches to the remote, use git push origin branch-name. If the push fails, first use git pull to grab Remote new commit
When git clone, only the main branch is cloned by default. If you want to clone all branches, you need to create it manually. To create the branch corresponding to the remote branch locally, use git checkout -b branch-name origin/branch-name, local Same as the name of the remote branch
Error:
[root@jinkai newfile]# git checkout -b dev origin/dev
fatal: Cannot update paths and switch to branch 'dev' at the same time.
Did you intend to checkout 'origin/dev' which can not be resolved as commit?
Solution one:
Create a local branch
git checkout -b dev
Then reset his starting point
git reset --hard origin/dev
Run git fetch origin, and make sure that the remote dev branch does exist before running.
[root@jinkai newfile]# git branch
admin
* dev
main
Solution two:
git remote show origin
git remote update
git fetch
git checkout -b dev origin/dev
Label management
The label is similar to the snapshot function, you can put a label on the version library to record the state of the library at a certain time. It can also be restored to this state at any time.
git checkout main // first cut to the main branch
git tag v1.0 //tag main v1.0
git show v1.0 //View label information
git tag //You can view all tags
tag is for the commit, so you can tag for the historical commit
git log --pretty=oneline --abbrev-commit //Check the historical commit first
git tag v0.9 f60f5d1 //Tag for historical commit
git tag -a v0.8 -m "tag just v1.1 and so on" 1cdb957 //You can describe the tag
git tag -d v0.8 //Delete the tag
git push origin v1.0 //Push the specified label to the remote
git push --tag origin //Push all tags
If you delete a label locally, you need to do this if you want to delete it remotely:
git tag v1.0 -d //Delete local tags
git push origin :refs/tags/v1.0 //Delete remote tags
[root@jinkai newfile]# git tag v1.0
[root@jinkai newfile]# git show v1.0
commit f2828c2b54dfd986da7a8798733b19bf82793145
Author: root <[email protected]>
Date: Sun Dec 13 00:08:24 2020 +0800
main file a.txt
diff --git a/a.txt b/a.txt
index 1383736..384c402 100644
--- a/a.txt
+++ b/a.txt
@@ -1,3 +1,2 @@
yyyy
mainmainmain
-adminadminadmin
[root@jinkai newfile]# git tag
v1.0
[root@jinkai newfile]# git log --pretty=oneline --abbrev-commit
f2828c2 main file a.txt
7baca4e main file a.txt
61ecf5b main file a.txt
3445592 admin file a.txt
269659a main file a.txt
13f3b30 touch 1.txt
957bc21 wowowo
f60f5d1 whowhowho
1cdb957 wowowo
c36e391 Update a.txt
d3b0dc5 new file a.txt
ca5f319 admin file a.txt
f701012 Update README.md
14cef13 Update README.md
f278ae1 first commit
[root@jinkai newfile]# git tag v0.9 f60f5d1
[root@jinkai newfile]# git tag -a v0.8 -m "tag just v1.1 and so on" 1cdb957
[root@jinkai newfile]# git tag
v0.8
v0.9
v1.0
[root@jinkai newfile]# git tag -d v0.8
Deleted tag 'v0.8' (was 16b3de5)
[root@jinkai newfile]# git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/jinkai-linux/newfile.git
* [new tag] v1.0 -> v1.0
[root@jinkai newfile]# git push --tag origin
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/jinkai-linux/newfile.git
* [new tag] v0.9 -> v0.9
[root@jinkai newfile]# git tag v0.9 -d
Deleted tag 'v0.9' (was f60f5d1)
[root@jinkai newfile]# git push origin :refs/tags/v0.9
To https://github.com/jinkai-linux/newfile.git
- [deleted] v0.9
git alias
Is the git commit command a bit long? Using aliases can improve our work efficiency
git config --global alias.ci commit //ci is the alias commit is the original command
git config --global alias.co checkout
git config --global alias.br branch
View git alias using command
git config --list |grep alias
Tips for query log:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
Cancel alias
git config --global --unset alias.br
View alias configuration file
cat /root/.gitconfig
[root@jinkai newfile]# git config --global alias.ci commit
[root@jinkai newfile]# git config --global alias.co checkout
[root@jinkai newfile]# git config --global alias.br branch
[root@jinkai newfile]# git config --list |grep alias
alias.ci = comma
alias.co=checkout
alias.br=branch
[root@jinkai newfile]# git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset-%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
[root @ jinkai newfile] # git lg
* f2828c2- (HEAD, tag: v1.0, origin/main, origin/admin, main, admin) main file a.txt (21 hours ago) <root
* 7baca4e- main file a.txt (21 hours ago) <root>
|\
| * 3445592- admin file a.txt (21 hours ago) <root>
-------------------------------------------------------
[root@jinkai newfile]# git config --global --unset alias.br
[root@jinkai newfile]# git config --list |grep alias
alias.ci = comma
alias.co=checkout
alias.lg=log --color --graph --pretty=format:'%Cred%h%Creset-%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
[root@jinkai newfile]# cat /root/.gitconfig
[user]
name = root
email = [email protected]
[push]
default = matching
[alias]
ci = commit
co = checkout
lg = log --color --graph --pretty=format:'%Cred%h%Creset-%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commi
Build a git server
After all, github is public, and private warehouses have to be bought. So we can find a way to build a private one, which is only used by our own company. Gitlab is a good choice. Before introducing it, let's talk about the command line git server
To find a server, first install git, yum install -y git
Add a git user and set the shell to /usr/bin/git-shell, the purpose is to prevent the git user from logging in remotely
useradd -s /usr/bin/git-shell git
cd /home/git
Create an authorized_keys file, and change the owner, group and permissions to store the public key on the client machine
mkdir .ssh
touch .ssh/authorized_keys
chown -R git:git .ssh
chmod 600 .ssh/authorized_keys
Determine the directory where the git repository is stored, such as /data/gitroot
mkdir /data/gitroot
cd / data / gitroot
git init --bare sample.git // A bare warehouse will be created. The bare warehouse has no workspace, because the Git warehouse on the server is purely for sharing, so users are not allowed to log in to the server directly to change the workspace, and the Git repositories usually end in .git
chown -R git:git sample.git
The above operations are done on the git server. Usually, the git server does not require developers to log in to modify the code. It only acts as a server, just like github. The usual operations are done on our own pc.
First, put the public key on the client into the /home/git/.ssh/authorized_keys file on the git server
Clone the remote warehouse on the client (own pc)
git clone git@ip:/data/gitroot/sample.git
At this point, you can generate a sample directory in the current directory, this is the remote we cloned
The warehouse is out. Enter into this, you can develop some code, and then push to the remote, or clone on the server to the client.
[root@jinkai05 ~]# yum install -y git
[root@jinkai05 ~]# useradd -s /usr/bin/git-shell git
[root@jinkai05 ~]# cd /home/git/
[root@jinkai05 git]# mkdir .ssh
[root@jinkai05 git]# touch .ssh/authorized_keys
[root@jinkai05 git]# chown -R git:git .ssh
[root@jinkai05 git]# chmod 600 .ssh/authorized_keys
[root@jinkai05 git]# mkdir /data/gitroot
[root@jinkai05 git]# cd !$
cd / data / gitroot
[root @ jinkai05 gitroot] # git init --bare sample.git
Initialize an empty Git repository in /data/gitroot/sample.git/
[root @ jinkai05 gitroot] # chown -R git: git sample.git /
[root @ jinkai05 gitroot] # vim /home/git/.ssh/authorized_keys
[root@jinkai05 gitroot]# cat !$
cat /home/git/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDsGH9A1mo0IRXhrBsWO9Zpkv45nJT14tYQhPt6BEN/17VPESvHVP0Ur0cVIG571Nh1yyCcLBzInDsR4UVRrexUp6j7NNXv9qA/89DomYFp3W67WLch2fa4WkX2xeKxoZR0RJpnQK0NS5EOhe9vrI5aAJe/OsVOfMoHB8HJI/rPsS9mLmOG+PVSmQzokF4DYRmOXB/+eZ0H0Rwoy8W87WF269yliaQQMPsGgJK+1kYhqIkEk80fEE6kGd1ZR0gSLoYYXrmSVhOhLis3TKGQLe4UqpuuV95MFmcaT1yvUVnuAqNRjmxs/hia6htySbGibcF4OmjKQU+ZFh2q+Sk1Xx147OsiT3w9WPd+QQTHvDWlN1QyPER7elSf65mcuX8QFz1WB/gv+sQ+qNwd+9C2xV5WtacD+1/QU6XQOD48mKl3VbazJoZ8K0DTYmqsm+J9Y2QuuXQ8iLBNH0zvxh3zBGpdd140q8VitAxbGA98aiXURA2D+jatlEZKMmKPlCu4JuGdsTsTex+na9+Wi0/PthfIkzcDjMFNoRHMkMhBJfTz2t/bOW4EgDBni0JrP66JHIMg9s2QN0O1fRtEQzcimT3FpndhYDgrM4b1G+4K41oE+rj9tAe7sVSG2afxbDY4p53988Oze9lxPwPE2+JT8z+ztRlfCRZqm0o3BVzclQ8G4w== [email protected]
[root@jinkai newfile]# git clone [email protected]:/data/gitroot/sample.git
Cloning into 'sample'...
The authenticity of host '192.168.111.140 (192.168.111.140)' can't be established.
ECDSA key fingerprint is SHA256:GnZadcz8FK3PLcgNXjhMWbz0Qgqi2LvbqaoR+wLdV9Q.
ECDSA key fingerprint is MD5:00:10:2a:88:19:39:d4:58:7d:7a:22:0d:03:bb:82:0a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.111.140' (ECDSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.
[root @ jinkai newfile] # ls
1.txt README.md a.txt sample
[root@jinkai sample]# echo aaaaa > a.txt
[root@jinkai sample]# git add a.txt
[root@jinkai sample]# git commit -m "ch a.txt"
[master (root-commit) d75b190] ch a.txt
1 file changed, 1 insertion(+)
create mode 100644 a.txt
[root@jinkai sample]# git push
No refs in common and none specified; doing nothing.
Perhaps you should specify a branch such as 'master'.
fatal: The remote end hung up unexpectedly
error: failed to push some refs to '[email protected]:/data/gitroot/sample.git'
[root@jinkai sample]# git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 199 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To [email protected]:/data/gitroot/sample.git
* [new branch] master -> master
[root@jinkai sample]# cd /tmp/
[root @ jinkai tmp] # git clone [email protected]: /data/gitroot/sample.git
Cloning into 'sample'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
[root@jinkai tmp]# ls sample/
a.txt
[root@jinkai tmp]# cat sample/a.txt
aaaaa