Linux中git安装及命令

Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件

Git重要的操作示例图如下:

 

大家工作的地方就是workspace, 首先要从远程仓库中将项目clone到本地Repository中分支 

分支就是便于多人在同一项目中的协作开发,每个人开发不同的功能,在各自的分支开发过程中互不影响,完成后都提交到各自的 dev分支 ,然后在将每个人的分支合并到master分支。发布代码都是从master分支来发布。

我们在创建一个dev分支:git结构图如下:

 

我们在dev分支做一些修改,然后提交(commit). 生成的git结构图如下

 

我们在dev分支和master分支上分别做一些修改,然后提交(commit). 生成的git结构图如下

合并分支的两中方法merger和rebase

1) 将dev分支合并(merge)到master

假设我们有一个主分支 master 及一个开发分支 dev,然后合并提交(merge commit)将两个分支的历史连在了一起。

切换到 master 分支,执行以下命令:

 $ git merge dev  #将dev分支合并到当前master分支

合并分支过程如下,会生成一个新的节点:

 

2) 将dev分支合并(rebase)到master

如果你想让"master"分支历史看起来像没有经过任何合并一样,你也许可以用 git rebase ,操作就叫做变基,即更改各个分支的基类

$ git checkout master
$ git rebase dev
这些命令会把你的"master"分支里的每个提交(commit)取消掉,并且把它们临时保存为补丁(patch)(这些补丁放到".git/rebase"目录中),
把dev分支的历史记录会添加在master分支的后面,然后把"master"分支更新为最新的"dev"分支,最后把保存的这些补丁应用到"master"分支上。
当'master'分支更新之后,它会指向这些新创建的提交(commit),而那些老的提交会被丢弃, 完成后的git机构记录成一条线。 如果运行垃圾收集命令(pruning garbage collection), 这些被丢弃的提交就会删除. (请查看 git gc)

 

冲突 

合并的时候,有可能会产生冲突。冲突的产生是因为在合并的时候,不同分支修改了相同的位置。所以在合并的时候git不知道那个到底是你想保留的,所以就提出疑问(冲突提醒)让你自己手动选择想要保留的内容,从而解决冲突。在解决了所有冲突之后,重新提交代码,然后你的代码就和主仓库保持一致了

 

linux下git的安装

[root@xzkj-huanan2 download]# wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.19.0.tar.gz
[root@xzkj-huanan2 download]# tar -zxvf git-2.19.0.tar.gz
[root@xzkj-huanan2 download]# cd git-2.19.0
[root@xzkj-huanan2 download]# ./configure prefix=/usr/local/git
[root@xzkj-huanan2 download]# make prefix=/usr/local/git all
[root@xzkj-huanan2 download]# make prefix=/usr/local/git install
[root@xzkj-huanan2 download]# echo "export PATH=$PATH:/usr/local/git/bin" > /etc/profile.d/git.sh
[root@xzkj-huanan2 download]# source /etc/profile.d/git.sh
[root@xzkj-huanan2 download]# git --version 

初始化Git 创建一个裸仓库

在服务器中创建一个仓库,即我们的远程仓库Remote;    创建一个git用户,git登陆上传时用ssh,所以要创建一个用户

[root@iZ231tx6fm4Z src]# useradd gituser
[root@iZ231tx6fm4Z src]# passwd gituser
[root@iZ231tx6fm4Z src]# mkdir git
[root@iZ231tx6fm4Z git]# cd git

[root@iZ231tx6fm4Z git]# git init --bare project.git    
[root@iZ231tx6fm4Z git]# chown -R gituser:git project.git         //将project.git文件夹赋予gituser用户

禁用shell登录, 出于安全考虑,第二步创建的git用户不允许登录shell,

[root@iZ231tx6fm4Z dev]# which git-shell
/usr/bin/git-shell

【/etc/passwd 文件格式】
在该文件中,每一行用户记录的各个数据段用":"分隔,分别定义了用户的各方面属性。
各个字段的顺序和含义如下:

用户名:密码:用户编号:组编号:注解:用户主目录:登录Shell

密码: 需要注意的是,如果此字段中的第一个字符是"*"的话,那么,就表示该账号被查封了,系统不允许持有该账号的用户登录

注解: 这是给用户帐号做的注解
它一般是用户真实姓名、电话号码、住址等,当然也可以是空的。

登录Shell:用户登录后执行的命令
一般来说,这个命令将启动一个shell程序(此程序不是一个命令解释器), 利用这一特点,我们可以限制用户只能运行指定的应用程序,在该应用程序运行结束后,用户就自动退出了系统


【/etc/group】
如:
mosquitto:x:499:
mqtt:x:500:
rabbitmq:x:498:
git:x:501:guo


组名:口令:组标识号:组内用户列表
1)“组名”是用户组的名称,由字母或数字构成。与/etc/passwd中的登录名一样,组名不应重复。
2)“口令”字段存放的是用户组加密后的口令字。一般Linux系统的用户组都没有口令,即这个字段一般为空,或者是*。
3)“组标识号”与用户标识号类似,也是一个整数,被系统内部用来标识组。
4)“组内用户列表”是属于这个组的所有用户的列表/b],不同用户之间用逗号(,)分隔。这个用户组可能是用户的主组,也可能是附加组。


找到类似下面的一行(dev表示用户名):

dev:x:503:504::/home/dev:/bin/bash
改为:
dev:x:503:504::/home/dev:/usr/bin/git-shell 

在tortoisegit上使用密钥

在安装TortoiseGit的时候其实会让你选择默认使用的ssh客户端,默认情况下是使用TortoiseGitPlink这个客户端。

指定ssh的客户端为TortoiseGit

生成putty密钥

在安装tortoisegit的时候,默认还会安装有Puttygen.exe这个程序,这个程序是可以生成putty密钥的。

点击Generate按钮后会按一个进度条,然后鼠标不断在该程序内动,目的是生成一些随机数。注:如果鼠标不动,进度条非常的缓慢 

putty密钥生成, 点击save private key保存putty的私钥,putty的密钥的后缀名是ppk。

在服务器上添加openssh公钥

我们在上面创建了putty的密钥对,现在需要将生成的公钥添加到服务器上。

其实这里也可以把公钥添加到github.com上,也是可以使用的。 putty生成的公钥是和openssh的的公钥是相同的,他们只是私钥不同

假设刚刚生成的公钥是

ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAi1vfwiNbamTPUOSpEWvQDYrefFcuPkUuZe5Y6r4l/xEAv7e9f5QDr6QEo215r2qBBnuixAgzpjZPSvr7S51qinuq6EyXm4kFGIW6B/L4zVjx5DKxofTno39xe58QQnAixoHNN9ccNhetcxEjp7gORo1k7AMuMuQY7V/6aekiOPfh6QsWuUMf6HZhZMqpu3q3xAqHlmOU5emAif4bQKZFghEYOftHZH+E+Yo+ed65KtOJ+V5PjPxD6RMGfx3A7MhsV5PXDijD7yu0b33r+mEDLoqRO1RDQUoviryBbuE4Gcu63a3J8+3GifXbrXOHzlMipAYtHxHjg5XuLGENlEmodw== rsa-key

登录到服务器的需要添加公钥的用户名下,比如git这个用户名。

cd /home/git/
mkdir .ssh #如果这个目录不存在
chmod 700 .ssh    #目录的权限为 700
touch .ssh/authorized_keys #如果这个文件不存在
chmod 600 .ssh/authorized_keys #设置一下文件的权限
echo "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAi1vfwiNbamTPUOSpEWvQDYrefFcuPkUuZe5Y6r4l/xEAv7e9f5QDr6QEo215r2qBBnuixAgzpjZPSvr7S51qinuq6EyXm4kFGIW6B/L4zVjx5DKxofTno39xe58QQnAixoHNN9ccNhetcxEjp7gORo1k7AMuMuQY7V/6aekiOPfh6QsWuUMf6HZhZMqpu3q3xAqHlmOU5emAif4bQKZFghEYOftHZH+E+Yo+ed65KtOJ+V5PjPxD6RMGfx3A7MhsV5PXDijD7yu0b33r+mEDLoqRO1RDQUoviryBbuE4Gcu63a3J8+3GifXbrXOHzlMipAYtHxHjg5XuLGENlEmodw== rsa-key" >> .ssh/authorized_keys #这个和上面是同一行的

注意:公钥在authorized_keys的文件形式是一行一个公钥,切记。否则该公钥不起作用。

在Git服务器上首先需要将/etc/ssh/sshd_config中将RSA认证打开:

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

然后 systemctl restart sshd.service ,重启ssh 

在/home/git下创建.ssh目录,然后创建authorized_keys文件,把id_rsa.pub里面的内容复制到authorized_keys文件中

公钥已经添加到服务器去了,接下来就是在客户端上设置密钥了。

git clone的时候使用,如下设置:

git clone设置putty私钥

这样就可以搞定了。

putty密钥与openssh密钥转化

如果你有putty的私钥了,但是想在ssh客户端下使用openssh的私钥,再去生成一个openssh的密钥对比较麻烦。

  1. 点击Conversions菜单项中的Import key
  2. 选择一个putty的私钥或者openssh的私钥
  3. 点击save private key保存为putty的私钥
  4. 或者点击菜单Conversions->Export OpenSSH Key保存为openssh的私钥

比较常用的Git bash命令

1:查看远程分支

$  git branch -a 

2:查看本地分支

$ git branch

查看各个分支最后一次提交: $ git branch -v
查看哪些分支合并入当前分支: $ git branch –merged
查看哪些分支未合并入当前分支: $ git branch –no-merged

3:创建分支, 从当前分支中创建

$ git branch test001
$ git checkout test001

也可以一步完成,创建分支并切换分支: $ git checkout -b test001

4:把新创建的分支推到远端

$ git push origin test001

建立本地到上游(远端)仓的链接 – 这样代码才能提交上去
将本地的分支和远程的分支关联起来,下次使用git pull 或者git push的时候,不需要这样:

git push origin test001
git pull origin test001
git push -v --progress "origin" test001:test001

建立分支关联命令:需要执行下面的命令:
git branch --set-upstream-to=origin/test001
关联建立后就可以直接执行 以下命令来获取和推送数据
git pull 和git push

5:删除本地分支(要先切换到其他)

$ git checkout master //切换到master分支

$ git branch
 api0622
* master
 test

#删除操作
$ git branch -d test
#查看操作

$ git branch
 api0622
* master

删除远程版本(用一个空的去更新它,就相当于删除了)
$  git push origin :test 

6:合并分支(将分支test合并到master):

$ git checkout master
$ git merge test 

7:查看git分支是从哪个源分支建立出来的

git reflog --date=local | grep 分支名

比如以下操作 

$ git reflog --date=local | grep uat_worktime0403
e00166f HEAD@{Fri Apr 14 18:04:42 2023}: checkout: moving from uat to uat_worktime0403
0ad5df6 HEAD@{Fri Apr 14 17:59:59 2023}: merge uat_worktime0403: Merge made by the 'ort' strategy.
61a5902 HEAD@{Fri Apr 14 17:59:36 2023}: checkout: moving from uat_worktime0403 to uat
61a5902 HEAD@{Mon Apr 3 13:42:04 2023}: checkout: moving from uat to uat_worktime0403 

最下面一行,moving from uat to uat_worktime0403   表示看出当前查询的分支是从uat分支中拉取建立的 

差异比较命令

1. 显示出branch1和branch2中差异的部分
git diff branch1 branch2 --stat

2. 显示指定文件的详细差异
git diff branch1 branch2 具体文件路径

3. 显示出所有有差异的文件的详细差异
git diff branch1 branch2

4. 查看branch1分支有,而branch2中没有的log
git log branch1 ^branch2

5. 查看branch2中比branch1中多提交了哪些内容
git log branch1..branch2
注意,列出来的是两个点后边(此处即dev)多提交的内容。

6. 不知道谁提交的多谁提交的少,单纯想知道有什么不一样
git log branch1...branch2

7. 在上述情况下,在显⽰出每个提交是在哪个分⽀上
git log -lefg-right branch1...branch2
注意 commit 后面的箭头,根据我们在 –left-right branch1…branch2 的顺序,左箭头 < 表示是 branch1 的,右箭头 >表示 是branch2的

 

详细的git命令

 

git init #初始化
git status #获取状态
git add [file1] [file2] ... # .或*代表全部添加或者-A
git commit -m "message" #将内容提交,在冒号里面最好填写英文注释
git remote add origin git@github.com ##此时本地工程与远程仓库已经建立了联系
git push -u origin master #将本地的内容同步到远程仓库中
git show [十六进制码] #显示某一个特定的提交的日志
git log #查看自己提交的历史
git ls-files -u #查看冲突未处理的文件列表
git pull origin master #获取最新的远程仓库代码
git stash list #获取暂存列表

git add -A #跟踪新文件

git add -u [path] # 添加[指定路径下]已跟踪文件

rm *&git rm * # 移除文件

git rm -f * # 移除文件

git rm --cached * # 停止追踪指定文件,但该文件会保留在工作区

git mv filefrom fileto # 重命名跟踪文件

git log # 查看自己提交的历史

# 提交操作:
git commit # 提交更新
git commit [file1] [file2] ... # 提交指定文件
git commit -a #跳过使用暂存区域,把所有已经跟踪过的文件暂存起来一并提交
git commit --amend #修改最后一次提交
git commit -v #提交时显示所有diff信息

# 撤销操作:
git reset HEAD *    #取消已经暂存的文件
git reset --soft HEAD * #重置到指定状态,不会修改索引区和工作树
git reset --hard HEAD * #重置到指定状态,会修改索引区和工作树
git reset -- files #重置index区文件
git reset --hard 11d881aea55e844dc0ebf0f3e5bf12a3ca999001 # 还原指定的提交之前的状态
git revert HEAD~ #还原前前一次操作
git checkout -- file #取消对文件的修改(从暂存区——覆盖worktree file)
git checkout branch | tag|commit -- file_name   #从仓库取出file覆盖当前分支
git checkout -- .   #从暂存区取出文件覆盖工作区

# 查看差异:
git diff file #查看指定文件的差异
git diff --stat #查看简单的diff结果
git diff #比较Worktree和Index之间的差异
git diff --cached #比较Index和HEAD之间的差异
git diff HEAD #比较Worktree和HEAD之间的差异
git diff branch #比较Worktree和branch之间的差异
git diff branch1 branch2 #比较两次分支之间的差异
git diff commit commit #比较两次提交之间的差异

# 日志查看:
git log 查看最近的提交日志:
git log --pretty=oneline #单行显示提交日志
git log --graph # 图形化显示
git log --abbrev-commit # 显示log id的缩写
git log -num #显示第几条log(倒数)
git log --stat # 显示commit历史,以及每次commit发生变更的文件
git log --follow [file] # 显示某个文件的版本历史,包括文件改名
git log -p [file] # 显示指定文件相关的每一次diff

# 储藏操作:
git stash #将工作区现场(已跟踪文件)储藏起来,等以后恢复后继续工作。
git stash list #查看保存的工作现场
git stash apply #恢复工作现场
git stash drop #删除stash内容
git stash pop #恢复的同时直接删除stash内容
git stash apply stash@{0} #恢复指定的工作现场,当你保存了不只一份工作现场时。

# 分支操作:
git branch -b test #创建并切换test分支
git branch #列出本地分支
git branch -r #列出远端分支
git branch -a #列出所有分支
git branch -v #查看各个分支最后一个提交对象的信息
git branch --merge #查看已经合并到当前分支的分支
git branch --no-merge #查看为合并到当前分支的分支
git branch branch [branch|commit|tag] # 从指定位置出新建分支
git branch --track branch remote-branch # 新建一个分支,与指定的远程分支建立追踪关系
git branch -m old new #重命名分支
git branch -d test #删除test分支
git branch -D test #强制删除test分支
git branch --set-upstream dev origin/dev #将本地dev分支与远程dev分支之间建立链接
git checkout test #切换到test分支
git checkout -b test dev#基于dev新建test分支,并切换

git merge test #将test分支合并到当前分支
 
# 变基操作
git rebase master #将master分之上超前的提交,变基到当前分支
git rebase --onto master 119a6 #限制回滚范围,rebase当前分支从119a6以后的提交
git rebase --interactive #交互模式
git rebase --continue# 处理完冲突继续合并
git rebase --skip# 跳过
git rebase --abort# 取消合并

 
# 远程分支操作:
git fetch origin remotebranch[:localbranch] #从远端拉去分支[到本地指定分支]
git pull origin remotebranch:localbranch #拉去远端分支到本地分支
git push origin branch #将当前分支,推送到远端上指定分支
git push origin remote branch # 删除远端指定分支
git push origin remote branch --delete # 删除远程分支
git branch -dr branch # 删除本地和远程分支
git checkout -b [--track] test origin/dev#基于远端dev分支,新建本地test分支[同时设置跟踪]
#git是一个分布式代码管理工具,所以可以支持多个仓库,服务器上的仓库在本地称之为remote. git remote add origin #地址 git remote #显示全部远程仓库 git remote –v #显示全部源
+详细信息 git remote rename origin1 origin2 #重命名 git remote rm origin #删除 git remote show origin #查看指定源的全部信息 # 标签操作: git tag #列出现有标签 git tag -a v0.1 -m 'my version' #新建带注释标签 git checkout tagname #切换到标签 git push origin v1.5 #推送分支到远程仓库上 git push origin –tags #一次性推送所有分支 git tag -d v0.1 #删除标签 git push origin :refs/tags/v0.1 #删除远程标签 git push origin #推送标签到远程仓库 $git push origin master:master (在local repository中找到名字为master的branch,使用它去更新remote repository下名字为master的branch,如果remote repository下不存在名字是master的branch,那么新建一个) git push origin :refs/tags/ #删除远程标签需要先删除本地标签 git checkout # 放弃工作区的修改 git reflog #显示本地执行过git命令 git remote set-url origin #修改远程仓库的url git whatchanged --since='2 weeks ago' #查看两个星期内的改动 git ls-files --others -i --exclude-standard #展示所有忽略的文件 git clean -X -f #清除gitignore文件中记录的文件 git status --ignored #展示忽略的文件

 

 

用git之外的用户登录,出现下列错误
remote: error: insufficient permission for adding an object to repository database ./objects
remote: fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit

解决如下:

//进入代码仓库
cd android.git
//改变代码仓库下,所有文件的访问权限,同组可写
sudo chmod -R g+ws *

//改变代码仓库下,所有文件的访问属性
chgrp -R mygroup *
//更新配置
git repo-config core.sharedRepository true

 

参考:

 Git 少用 Pull 多用 Fetch 和 Merge】http://www.oschina.net/translate/git-fetch-and-merge

分支合并】http://www.cnblogs.com/wangmingshun/p/5425150.html

 

问题:提示:OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443

Git的Http代理的问题,Git支持三种协议:git://、ssh:// 和 http://,本来push的时候应该走ssh隧道的,但是因为设置了http代理,所以就走了http的代理,于是就提交不了了。

Administrator@DESKTOP-96GBGI7 MINGW64 /f/downloads/mediapipe_repo
$ git config --global --unset http.proxy

Administrator@DESKTOP-96GBGI7 MINGW64 /f/downloads/mediapipe_repo
$ git clone https://github.com/google/mediapipe.git
Cloning into 'mediapipe'...
remote: Enumerating objects: 11178, done.
remote: Counting objects: 100% (436/436), done.
remote: Compressing objects: 100% (263/263), done.
Receiving objects:   3% (348/11178), 107.60 MiB | 9.98 MiB/s 

 

在 .gitignore 文件中,如果添加了 file/ 这样的规则,但发现对应的目录或文件仍然没有被忽略,可能有以下原因:

1. 规则生效前文件已被追踪
如果在添加 .gitignore 规则之前,file/ 目录或其内容已经被 Git 跟踪(即已经提交到版本库),那么 .gitignore 对这些文件无效。
解决方法:
# 停止跟踪已忽略的文件,但保留本地文件
git rm --cached -r file/

比如现将添加到 .gitignore 文件中

 在执行  git rm --cached -r SR.UI/obj


2. 规则格式问题
确保 .gitignore 中的规则是正确的。例如:
file/ 表示忽略名为 file 的目录及其所有内容。
如果要忽略文件而不是目录,应该写成 file 或 file/*。
检查规则:
确认 .gitignore 文件中是否有其他规则覆盖或冲突。
3. 路径匹配问题
如果 file/ 是一个子目录,确保 .gitignore 文件位于正确的层级。
如果需要全局忽略,可以在根目录的 .gitignore 文件中定义。
4. 缓存问题
有时 Git 缓存可能导致规则未立即生效。
清理缓存并重新应用规则:

git rm -r --cached .
git add .
git commit -m "Update .gitignore rules"


5. 检查当前状态
使用以下命令检查 file/ 是否仍在被跟踪:

git ls-files | grep "file/"

如果仍有输出,说明该目录或其内容仍被 Git 跟踪。

总结
根据以上可能性逐一排查,通常问题出在规则生效前文件已被追踪或规则书写不正确。调整后记得重新提交更改以确保忽略规则生效。
  

posted @ 2016-06-16 16:05  南极山  阅读(1177)  评论(0)    收藏  举报