git版本控制的常规用法

文章目录


最近在改服务器上改代码的时候,每次都要在本地备份,有时在本地改完还要同步,搞多个版本把我自己都搞乱了,是时候使用git了。 我的需求之一就是在多台机器上操作,能够同步,在服务器上能下载最新的版本, 更改后再更新到仓库,git可以解决我的需求,github作为仓库,有的时候网络不稳定,gitee更快一点,所以就选择gitee作为远程仓库。

gitee

首先要创建gitee账户,再新建仓库。

linux系统

安装git , 配置密钥,然后就可以拉取或者更新。

# 源里有git,直接yum安装即可
yum -y install git
# 新建一个文件夹,作为gitee仓库交互的仓库
mkdir gitee && cd gitee 
# git 初始化
git init 
# 配置用户
git config --global user.name "yuanwl"
git config --global user.email "yuan.wanli@qq.com"
# 配置远端地址 - 目标远程仓库的下载链接
git remote add origin https://gitee.com/yuanwl/k8s.git
# 会生成一些配置文件,看一下
[root@node61 gitee]# ll -a
drwxr-xr-x   8 root root 4096 Dec 15 15:39 .git
[root@node61 gitee]# ll -a .git/
total 60
drwxr-xr-x  2 root root 4096 Dec 15 10:39 branches 
# 分支
-rw-r--r--  1 root root    5 Dec 15 15:31 COMMIT_EDITMSG
# commit 信息
-rw-r--r--  1 root root  352 Dec 15 15:39 config
# 配置文件
-rw-r--r--  1 root root   73 Dec 15 10:39 description
-rw-r--r--  1 root root   82 Dec 15 14:35 FETCH_HEAD
-rw-r--r--  1 root root   23 Dec 15 10:39 HEAD
drwxr-xr-x  2 root root 4096 Dec 15 10:39 hooks
# 命令
-rw-r--r--  1 root root 1241 Dec 15 15:30 index
drwxr-xr-x  2 root root 4096 Dec 15 10:39 info 
drwxr-xr-x  3 root root 4096 Dec 15 10:45 logs
# 日志
drwxr-xr-x 55 root root 4096 Dec 15 14:56 objects 
-rw-r--r--  1 root root   41 Dec 15 14:35 ORIG_HEAD
drwxr-xr-x  5 root root 4096 Dec 15 14:36 refs 
# 许多文件也不清楚作用, 但应该git配置和操作的信息都在这

git配置后之后,已经可以和gitee或其他线上仓库交互了,比如拉取一个仓库

git clone origin https://gitee.com/yuanwl/k8s.git
# 或者
git pull origin https://gitee.com/yuanwl/k8s.git

可以在本地修改同步到远程仓库

# 例如刚修改了 README.md, 提交到暂存区
git add README.md 
# 这就告诉了git, 做了哪些修改
git commit -m "test"
# commit就是确认提交到了本地仓库, -m 的参数是这次提交的注释,虽然写注释有点麻烦,但是写一下还是有用的,知道是提交了什么 
git push  
# 之后会提示输入用户和密码,然后就可以提交了

这是一个变更同步到仓库的过程,第一次接触可能会疑问,为什么不能一步到位,要三个命令才能同步呢?这是因为git的工作台机制,为了版本控制。

git版本控制的常规用法

# 测试
[root@node61 k8s]#echo "this is a test "work stage"" >> test.md 
# 更改后查看状态, not staged 
[root@node61 k8s]# git status  
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   test.md
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@node61 k8s]# git add test.md
# add后查看状态, not commited 
[root@node61 k8s]# git status 
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   test.md
#
[root@node61 k8s]# git commit -m "1"
[master 31f1e76] 1
 1 file changed, 1 insertion(+), 1 deletion(-)
 # commit后查看状态, 没有push
[root@node61 k8s]# git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#   (use "git push" to publish your local commits)
#
nothing to commit, working directory clean
[root@node61 k8s]# git push 
Counting objects: 5, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 271 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.2]
To https://gitee.com/yuanwl/k8s.git
   d664e8f..31f1e76  master -> master
# push之后,工作台干净了
[root@node61 k8s]# git status
# On branch master
nothing to commit, working directory clean

这样搞清了每一步要干啥,但麻烦的是每次都要输入账号密码。

# 可以配置记住密码
git config --global credential.helper store
# 产生一个文件 /root/.gitconfig
[root@VM-4-15-centos ~]# cat .gitconfig 
[credential]
	helper = store
[user]
	email = yuan.wanli@qq.com
	name = yuanwl
# 记录了账号与用户 
# 然后执行git pull 之后, 就会记住密码,存在/root/.git-credentials以后就不用输入了
[root@VM-4-15-centos ~]# cat .git-credentials 
https://yuanwl:123456789@gitee.com
# 这问题明显了,密码明文可见,一点都不安全,平时自己用用测试是可以的

ssh免密登陆

# 删除原有的通信方式 # 可选
git remote rm origin 
# 生成密钥
ssh-keygen 
# 将公钥~/.ssh/id_rsa.pub放在gitee公钥上,设置--ssh公钥--添加
# 添加ssh路径,git开头,和http路径不同 
git init git remote add origin 
git remote add origin git@gitee.com:uxpi/zsites.git
# 测试 
[root@node61 ~]# ssh -T git@gitee.com
Hi yuanwanli! You've successfully authenticated, but GITEE.COM does not provide shell access. 
# 然后就可以免密提交了

windows

我很多时候是在window多台主机上做修改。windows中在官网Git - Downloading Package (git-scm.com)下载git应用,安装一路next即可。

新建同步文件夹之后,右键选择 git bash here. 之后操作就和linux一样了。

进一步使用

删除文件, 如果删除了一个文件, 就不能git add filename ,可以使用 git rm确认删除了,然后commit.

rm -f test.md 
git rm test.md 
# 这样可能比较麻烦,有时也会忘,也没有关系。 如果在add 的时候提示: 
warning: You ran 'git add' with neither '-A (--all)' or '--ignore-removal',
whose behaviour will change in Git 2.0 with respect to paths you removed.
Paths like 'test.md' that are
removed from your working tree are ignored with this version of Git.

* 'git add --ignore-removal <pathspec>', which is the current default,
  ignores paths you removed from your working tree.

* 'git add --all <pathspec>' will let you also record the removals.
# 这时候再使用, git add -A 或者 git add --ignore-removal 也可以。
# 也可以直接用git rm test.md

另一种情况是, 如果是误删呢? 也可有恢复checkout

[root@node61 k8s]# git checkout -- test.md
[root@node61 k8s]# ls 
-rw-r--r-- 1 root root  320 Dec 16 16:04  test.md
# 文件回来了, 但只有commit之后才能恢复,没有commit的东西git根本不知道,也无法恢复。

如果我第二天不知道自己昨天改了什么呢?git diff

[root@node61 k8s]# git diff test.md
diff --git a/test.md b/test.md
index 90bfcb5..2178a28 100644
--- a/test.md
+++ b/test.md
@@ -1 +1,2 @@
 this is a test
+this is a test

如果我不知道现在改的文件有没有提交怎么办呢?git status

[root@node61 k8s]# git status test.md
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#   (use "git push" to publish your local commits)
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   test.md
#
no changes added to commit (use "git add" and/or "git commit -a")

当然了,在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们用git log可以查看:

[root@node61 k8s]# git log
commit 088a4167f946247ced6766c58ffd0568369ce69d
Author: yuanwl <yuan.wanli@qq.com>
Date:   Thu Dec 16 11:41:56 2021 +0800
    first commit 
commit ca0ffde7153d0f4eee8473cfa23797835ed74ae9
Merge: e72ac3d 259e9bf
# 可以看最近三次的提交日志 

版本回退,如果我提交了错误的修改,可以回退到上个版本

[root@node61 k8s]# git reset --hard HEAD^
HEAD is now at 818a7ff test
# 也可以根据版本commit 版本号回退, git reflog
[root@node61 k8s]# git reflog
d664e8f HEAD@{0}: pull: Fast-forward
818a7ff HEAD@{1}: reset: moving to HEAD^
d664e8f HEAD@{2}: pull: Fast-forward
818a7ff HEAD@{3}: commit: test
088a416 HEAD@{4}: clone: from https://gitee.com/yuanwl/k8s.git
[root@node61 k8s]# git reset HEAD 818a7ff

分支合并

分支合并是git中最核心的操作, 开始的时候只有一条分支master, 这样的问题是如果多人一起开发,那么可能出现每次push都会遇到别人修改的仓库。每个人一个分支, 在本地修改好再同步到master, 保证master是稳定的,其余分支是工作的。

git版本控制的常规用法

# 创建分支 
git branch lenovo 
# 切换分支  
git checkout lenovo 
# 切换到一个新的分支 git checkout -b levono 
# 查看分支 , 当前的分支前有星号 
$ git branch
* lenovo
  master
# 在levono分支修改后,切换回master分支是看不到修改内容的,需要同步一下。 
git merge lenovo 
# 同步有两种情况: 
# 1 lenovo只是新增了内容, 没有冲突, 可以快速合并 
# 2 lenovo上修改了内容,两条分支内容有冲突, 所以需要手动确认内容。 下面是冲突的情况
# lenovo 中 tesk.md 如下: 
$ cat test.md
which is the stable branch?
lenovo

# master 中tesk.md 如下:
$ cat test.md
which is the stable branch?
master

# 这是两个分支是有冲突的, git merge之后回提示需要手动解决冲突,冲突会在test.md文档中标记
$ cat test.md
which is the stable branch?
<<<<<<< HEAD   # 当前指向 
master
=======
lenovo
>>>>>>> lenovo  # lenovo分支内容  

# 需要手动修改文档成最终我们需要的内容,然后commit就同步了 
$ cat test.md
which is the stable branch?
master

# 删除分支 
git checkout -d lenovo 

# 本地lenovo分支推送远程master分支 
git push origin lenovo:master

# 拉取远程master到本地lenovo分子
git pull origin master:lenovo
# 总结就是 git push/pull origin  <源仓库名称>:<目标仓库名称>

标签

tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。

# 标签是commit的称呼,所以先看commit 
$ git log --abbrev-commit
commit 0e8c272 (HEAD -> master, tag: v3.0)
Author: yuanwanli <yuan.wanli@qq.com>
Date:   Sun Dec 19 10:52:18 2021 +0800

    add C 10.53

commit 98ea6fb
Author: yuanwanli <yuan.wanli@qq.com>
Date:   Sun Dec 19 10:51:54 2021 +0800

    add b 10.52

commit 8350365
Author: yuanwanli <yuan.wanli@qq.com>
Date:   Sun Dec 19 10:51:22 2021 +0800

    add a 10.51
# 给最近的修改加标签 
$ git ag v3.0 0e8c272
$ git tag v2.0 98ea6fb

# 查看标签列表 
$ git tag
v2.0
v3.0

# 查看标签明细
$ git show v3.0
commit 0e8c272709f6ac07155849fd7d0d3727161bf1f6 (HEAD -> master, tag: v3.0)
Author: yuanwanli <yuan.wanli@qq.com>
Date:   Sun Dec 19 10:52:18 2021 +0800

    add C 10.53

diff --git a/test.md b/test.md
index 422c2b7..de98044 100644
--- a/test.md
+++ b/test.md
@@ -1,2 +1,3 @@
 a
 b
+c

# 标签推送,讲v3.0推送到远端仓库
$ git push origin v3.0
Enumerating objects: 18, done.
Counting objects: 100% (18/18), done.
Delta compression using up to 8 threads
Compressing objects: 100% (11/11), done.
Writing objects: 100% (16/16), 1.20 KiB | 204.00 KiB/s, done.
Total 16 (delta 7), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.2]
To https://gitee.com/yuanwl/k8s.git
 * [new tag]         v3.0 -> v3.0

# 标签删除
$ git tag -d v2.0
Deleted tag 'v2.0' (was 98ea6fb)

问题解决

在push的时候遇到这样一个错误

error: failed to push some refs to ‘https://gitee.com/yuanwl/k8s.git’
Updates were rejected because the remote contains work that you do
not have locally. This is usually caused by another repository pushing
to the same ref. You may want to first merge the remote changes (e.g.,
hint: ‘git pull’) before pushing again.

就是线上的仓库在上次我clone之后有了改动(是我删了一个文件), 这样不能直接commit,

git会记下上次pull的版本,如果pull之后远程又做了修改,无法直接push, 这也很好理解,git不知道如何处理远程仓库的改动。

可以使用git pull同步。

ates were rejected because the remote contains work that you do
not have locally. This is usually caused by another repository pushing
to the same ref. You may want to first merge the remote changes (e.g.,
hint: ‘git pull’) before pushing again.

就是线上的仓库在上次我clone之后有了改动(是我删了一个文件), 这样不能直接commit,

git会记下上次pull的版本,如果pull之后远程又做了修改,无法直接push, 这也很好理解,git不知道如何处理远程仓库的改动。

可以使用git pull同步。

上一篇:git merge 简单的操作流程


下一篇:想要优雅地填报志愿?阿里云CDN为你加速