Git
Git操作
初始化
这是简单指南,可以放在收藏夹想不起来了拿起来看看.
装好之后先配置一下账户。
/etc/gitconfig
是系统级别的配置,使用--system,这些配置是会按级别覆盖的,仓库覆盖账户覆盖系统~/.gitconfig
下是账户级别的配置git config --global user.name "ooowl"
git config --global user.email "2411708618aqq.com"
作者是谁,仓库commit会有你的名字,名字和email(名字可以重复但email一般唯一)并不作为身份标识,只是一个标记而已所有的独立提交不记名只验证公钥或github账号,你可以通过这样来查看git config --local user.name
git config --local user.email
git init就会在该目录下生成一个.git文件夹,想知道这个文件夹里面是什么就自己去搜。git config --xxxx --list
显示本级下git 的配置
📌Tip
个人习惯git commit的信息类型[add,delete,fix,feature,end]-此功能第几次提交-其他描述
其实这个是有明确规范名的,小项目无所谓,大项目看项目需要,遵守github定义的规范还可以自动生成change logs
查看
git status
看看自己目前仓库里未跟踪的文件,修改未提交的文件
不用说的命令
git --version
git clone
克隆项目git add (.)
把文件添加到暂存区,未跟踪的文件可以直接添加为跟踪git fetch
从更新分支状态git pull
git commit -m "提交信息"
不常用但可能用到的命令
git show (id or tag)
查看这次id和tag的详细信息,包括提交时间作者提交了什么更改git log (--oneline --all --graph )
查看所有的提交记录,回滚需要至少7位id,-p查看提交具体干了啥,--all查看所有的分支,--graph 尽可能用图形表示。git blame File
查看File的更改提交历史 it rebase
不要用,会变基!!!
分支管理
你可以认为 HEAD(大写)是"current branch"(当下的分支)。当你用git checkout切换分支的时候,HEAD 修订版本重新指向新的分支。有的时候HEAD会指向一个没有分支名字的修订版本,这种情况叫”detached HEAD“
head(小写)是commit对象的引用,每个head都有一个名字(分支名字或者标签名字等等),但是默认情况下,每个叫master的repository都会有一个head, 一个repository可以包含任意数量的head。在任何时候,只要这个head被选择成为”current head“,那么这个head就成了HEAD,总是大写
先命令
git branch # 列出分支
git branch -vv # 列出分支和远程分支的关系
git branch dev 或者 git checkout -b dev # 创建一个新的分支 或者 创建一个新的分支并且切换过去
当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的工作目录的内容, 所以多个分支不需要多个目录
ignore参考
#
此为注释*.a
忽略所有.a结尾的文件!lib.a
但lib.a除外/todo
仅仅忽略项目根目录下的todo文件,不包括subdir/todobuild/*
忽略build/目录下的所有文件doc/*.txt
忽略doc/notes.txt(只忽略doc下本身的文件),但不包括doc/server/arch.txt(子目录下的文件)- 原来已经被跟踪的文件是无效的,必须先取消跟踪git rm --cache,下次提交就不会生效了
.idea/**/*
忽略某个(idea)文件夹下所有的文件和子文件夹(递归忽略所有)
服务器Git repo
申请用户
申请用户并设置密码,申请git组,把用到的用户加到这个组里,一般git就够了
groupadd git
useradd git -g git
passwd git
每个用户单独的ssh K,这样就可以一个用户对应一个工程互不影响,多个工程只要申请多个用户,放到git用户组更管理就可以了.
设置用户只能使用git禁止登陆ssh,并修改密码,编辑/etc/passwd
git:x:502:504::/home/git:/bin/bash //找到这一行
git:x:502:504::/home/git:/bin/git-shell//改为这个
添加客户机的公钥
你也可以不添加直接ssh克隆,但是这样会每次都让你输入密码,只把开发记得公钥添加就行了
首先在你的客户机上cmd运行
ssh-keygen -t rsa -C "xxxxx@mail.com"
//最后的是公钥里面显示的名字,自己开心就行
这样在下就得到了一对公钥和私钥id_rsa.pub
里面就是你的公钥复制下来
在服务器上root进入/etc/ssh
目录,编辑 sshd_config
,打开以下三个配置的注释:
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
/etc/rc.d/init.d/sshd restart //重启ssh
mkdir -p /home/git/.ssh
touch /home/git/.ssh/authorized_keys //新建了信任公钥
然后将客户机们的公钥id_rsa.pub
里面的内容复制到git用户的authorized_keys
里面
修改权限并创建仓库
在home下建立对应的工程最好,每个用管理自己的工程
sudo git init --bare /home/git/gitdemo.git
一定要修改权限!!!
免密登录也是这个权限,本身就是免密登录ssh传送的文件.
如果权限对的话就不用管
Warning
修改 .ssh 目录的权限为 700
修改 .ssh/authorized_keys 文件的权限为 600
仓库,.ssh目录和authorized_keys都要修改所有者
chmod 700 /home/git/.ssh
chmod 600 /home/git/.ssh/authorized_keys
chown -R git:git /home/git // 其实这一句就够了
chown -R git:git /home/git/.ssh
chown -R git:git /home/git/.ssh/authorized_keys
chown -R git:git /home/git/gitdemo.git //chown -R 所有者:组
连接远程分支
这时候客户机本地应该可以clone了,url有两种写法(推荐ssh)
git@192.168.0.100:/home/git/gitdemo.git //SCP写法
ssh://git@192.168.0.100/home/git/gitdemo.git //SSH写法
//Https的写法没有配置,而且每次都要输密码,团队协作不好用
如果是本地已经有repo了,可和远程连接起来git remote add origin git@192.168.0.100:/home/git/gitdemo.git
git push --set-upstream origin main
把本地的main分支和远程main关联起来(假设只有main分支)
pull,merge就可以用来了
冷知识,仓库的语言是server设置的,没用的知识增加了。
工作流参考
gitflow
gitflow工作流,团队开发的范例。
github工作流
主要流程为:
- 新建分支(Create a branch)
- 提交修改(Add commits)
- 创建PR(Open a Pull Request)
- 代码评审(Discuss and review your code)
- 部署(Deploy)
- 合并(Merge)
多平台换行符问题(LF or CRLF)
[1]
问题git提示code analyze的时候换行符是否要转换
文本文件所使用的换行符,在不同的系统平台上是不一样的。UNIX/Linux 使用的是 0x0A(LF)
,早期的 Mac OS 使用的是 0x0D(CR)
,后来的 OS X 在更换内核后与 UNIX 保持一致了。但 DOS/Windows 一直使用 0x0D0A(CRLF)
作为换行符
在不同平台上,换行符发生改变时,Git 会认为整个文件被修改,这就造成我们没法 diff
,不能正确反映本次的修改。
git使用git config --global core.autocrlf true
用于在提交和检出时自动转换换行符,选项有三个
true
提交时转换为LF,检出时转换为CRLFinput
提交时转换为LF,检出时不转换false
提交检出均不转换
git使用 git config --global core.safecrlf true
用于检查文件是否包含混合换行符,该配置也有三个可选项:
true
禁止提交混合换行符的文本文件(git add 的时候会被拦截,提示异常)warn
提交混合换行符的文本文件的时候发出警告,但是不会阻止 git add 操作false
不禁止提交混合换行符的文本文件(默认配置)
解决方法
直接无视然后提交,两个属性都设为false
不转换不警告,这样会造成换行符混乱,diff可能会失效
一种规范换行符的方式是这样的:
使用 Windows 系统的开发者设置:git config --global core.aurocrlf true
使用 Linux/MacOS 的开发者设置:git config --global core.autocrlf input
temp
git reflog
查看命令历史,以便确定要回到未来的哪个版本
git clone Address
克隆项目git add (.)
把文件添加到暂存区,未跟踪的文件可以直接添加为跟踪git restore
git push -u origin master
推送到 远程的master分支git fetch
从分支获取git pull
获取分支git commit -m "你的提交信息"
git checkout (id or -)(/path/file)
回到(某个or上一个)提交点,可以直接用tag名,跟文件名可以直接修改单独某个文件
git remote add Name RemoteAddress.git
添加一个远程仓库地址。
📌Tip
https是无状态的,使用https提交每次都要输入用户名和密码,SSH url克隆需要在克隆之前先配置和添加好SSH key,ssh默认是每次fetch和push代码都不需要输入账号和密码,如果你想要每次都输入账号密码才能进行fetch和push也可以另外进行设置。
git rm --cached 文件名
停止对git已跟踪的文件跟踪,但保留之前该文件的跟踪状态
在一个分支下开发,这种做法是没有问题的。即在 master 分支里,使用如上操作之后,config.js 就从 git 管理中剔除了,但是仍然存在于硬盘上。并不会影响到本地开发环境的正常调试。
如果同时满足以下条件的情况下就会出问题
1 多分支同时存在 config.php 文件。例如,master 分支,dev 分支都有 config.php 文件
2 一个分支删除了该文件,然后在另一个分支,merge 了该提交
这时候dev和master分支的config.js就全消失了。
git update-index --assume-unchanged 文件名
暂时让git忽略已跟踪的文件,具体看这一篇
虽然能达到(暂时的)目的,但并非最正确的做法,这样做是误解了 git update-index 的含义,而且这样做带来的最直接(不良)后果是这样的:
1 所有的团队成员都必须对目标文件执行:git update-index --assume-unchanged PATH。这是因为即使你让 Git 假装看不见目标文件的改变,但文件本身还是在 Git 的历史记录里的,所以团队的每个人在 fetch 的时候都会拉到目标文件的变更。(但实际上目标文件是根本不想被 Git 记录的,而不是假装看不见它发生了改变)
2 一旦有人改变目标文件之后没有 git update-index --assume-unchanged PATH 就直接 push 了,那么接下来所有拉取了最新代码的成员必须重新执行 update-index,否则 Git 又会开始记录目标文件的变化。这一点实际上很常见的,比如说某成员换了机器或者硬盘,重新 clone 了一份代码库,由于目标文件还在 Git 的历史记录里,所以他/她很可能会忘记 update-index。
git update-index --assume-unchanged 的真正用法是这样的:
1 你正在修改一个巨大的文件,你先对其git update-index --assume-unchanged
,这样 Git 暂时不会理睬你对文件做的修改;
2 当你的工作告一段落决定可以提交的时候,重置改标识:git update-index --no-assume-unchanged
,于是 Git 只需要做一次更新,这是完全可以接受的了;
3 提交+推送。
分支和合并
git branch xxx
产生一个新分支,想回到某个点获取分支可以先checkout
- 产生新分支 git checkout -b xxx
- 删除分支 git branch -d xxx
git merge xxx
将xxx合并到master,出现confilct的时候,大于号小于号和等号之间分别是两个分支不同的内容,最后需要在commit一次
和mrege的作用是一样的,不过结果不同。
Warning
merge会在head后面紧接着提交,合并后自动提交一次作为标记,worktree会有一个分支记录。
rebase会在分支根提交点处接着提交,之后再跟上master该节点之后的的提交,worktree不会有分支记录。