Git操作

2018.7.18 星期三 17:30

git –version
git init

github Page好像还区分大小写

配置

1
2
3
4
5
6
7
8
9
10
git config --list (全局,本地)
git config user.name user (修改本地/当前项目)
git config user.email user@fenhao.doulou
git config --global user.name user
git config --global --unset user.name

## 修改默认分支main
`git config --global init.defaultBranch main`

cat .git/config

常用git配置

1、npm使用淘宝镜像源
(能加快npm下载速度)
npm config set registry https://registry.npm.taobao.org
2、node-sass使用淘宝镜像
(能解决node-sass安装失败问题)

npm config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/

3、npm恢复官方镜像源
(发布npm包时必须切换回官方镜像源)

npm config set registry https://registry.npmjs.org
4、git 配置全局用户名、邮箱
(用于git本地仓库记录该代码作者的信息)

1
2
git config --global user.name neohan
git config --global user.email neohan666@qq.com

5、git 配置ssh
ssh-keygen -t rsa

6、git 配置全局字符集编码
(防止中文commit信息乱码)

1
2
3
git config --global i18n.commitencoding utf-8
git config --global i18n.logoutputencoding utf-8
export LESSCHARSET=utf-8

7、git 配置全局不自动转换换行符
(解决windows和max系统的默认换行符不一致问题)
git config --global core.autocrlf false

8、git 设置能检测文件名大小写
(在需要配置的项目根目录下运行该命令)
git config core.ignorecase false

配置vscode

code --help
git config --global -e
git difftool -t vimdiff

1
2
3
4
5
6
1)默认的 Git 编辑器是Nano。
git config --global core.editor "code --wait"
## 新窗口
git config --global core.editor 'code --wait --new-window'
## 撤销
git config --global --unset core.editor

1
2
3
4
5
6
7
8
9
# 2)默认的 Diff Tool 是vimdiff。
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'g'

git difftool --tool-help ## 以查看更多选项。
# 3) git没有设置默认的 Merge Tool 。
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
git mergetool --tool-help ## 以查看更多选项。

配置文件

1
2
3
4
5
6
7
8
9
10
[core]
editor = code --wait
[diff]
tool = vscode
[difftool "vscode"]
cmd = code --wait --diff $LOCAL $REMOTE
[merge]
tool = vscode
[mergetool "vscode"]
cmd = code --wait $MERGED

提交

git add .
git add -A
git add –all

git commit -m ‘mssd’
git am -m ‘sdfsf’s

status

On branch master
### “Changes not staged for commit:”
git 分为工作区和版本库,工作区是你的代码,版本库就是git记录了。
在修改进入版本库前有一个暂存区也叫索引,就是做git add 操作后记录的区域。
当commit的时候是将暂存区的记录添加到版本数据库。

你的提示说staged没有内容,也就是说你没有执行过add操作

### Untracked files:
no changes added to commit

分支

只删除本地/远程分支;同步本地已经删除

for-each-ref

列出远程Git分支按作者排序的committerdate

1
2
3
4
5
6
git for-each-ref --format='%(committerdate) %09 %(authorname) %09 %(refname)' | sort -k5n -k2M -k3n -k4n

git for-each-ref --format='%(committerdate) %09 %(authorname) %09 %(refname)' | sort -k5n -k2M -k3n -k4n|grep branch_A

# 查看某人提交的远程分支
git for-each-ref --format='%(committerdate) %09 %(authorname) %09 %(refname)' | sort -k5n -k2M -k3n -k4n|grep remote|grep someone

rev-parse

最近一次提交id

1
2
3
4
#### 完整
git rev-parse HEAD
#### short commit id
git rev-parse --short HEAD

show

git show –stat或git show -s用来获取最后一次commit的简介信息
show和log是不同的指令。虽然相似。
加上–format或–pretty来提取你想要的信息。如想要摘取author,则用’%an’:

1
git show -s --format=%an

–format的更多格式化格式

log

一堆参数

1
2
3
4
git show HEAD^:path/to/file  
git log --author=someone -2
git log --pretty=oneline
git log --pretty=format

–pretty=format:”%”

1
2
3
git log --pretty=format:"%s"
git log --pretty=format:"%an" -1
git log --pretty=format:"%cd" commitid -1

%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 -date= 选项定制格式
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期,按多久以前的方式显示
%s 提交说明

查找删除文件

git log -p filename (相对路径)
git log – [file_path]

1
2
3
4
5
6
7
# see the changes of a file, works even 
# if the file was deleted
git log -- [file_path]
# include stat parameter to see
# some statics, e.g., how many files were
# deleted
git log -1 --stat -- [file_path]

(上面只是看到的commit,不好使,下面的好用)
大多数我们是不知道在何时删除了某个文件,通过下面这个命令我们可以查看在哪个 commit 中删除了哪些文件。
git log –diff-filter=D –summary
比如我想恢复 ic_selected.png 这个文件,我们可以看到删除该文件对应的 commit id
这个命令会检出该 commit 的上一个提交中的文件,因为我们是在该 commit 中删除的文件,所以需要在上一个 commit 才能恢复出文件。
git checkout $commit~1 filename

最后的处理方式:通过git-history(vscode插件)查到历史提交大概删除日期,从该commit中创建并切换分支,找到文件复制出来恢复的。

远程仓库 remote

git remote
git remote -v
git remote add origin git://192.145.1.4:12/cloudclass.git
git remote set-url origin http://user@192.134.2:1001/r/cloudclass.git

远程分支同步本地

git远程删除分支后,本地git branch -a 依然能看到的解决办法。
使用命令 git remote show origin,可以查看remote地址,远程分支,还有本地分支与之相对应关系等信息。
根据提示,使用 git remote prune origin 命令:

拉取远程分支

获取远程分支到本地

1
2
3
4
5
6
7
# 采用此种方法建立的本地分支会和远程分支建立映射关系。
git checkout -b 本地分支名x origin/远程分支名x

# 采用此种方法建立的本地分支不会和远程分支建立映射关系。
git fetch origin 远程分支名x:本地分支名x

git branch --set-upstream-to origin/远程分支名 本地分支名

git 对比两个分支差异

git 对比两个分支差异

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

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

  3. 显示出所有有差异的文件的详细差异

git diff branch1 branch2

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

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

  3. 不知道谁提交的多谁提交的少,单纯想知道有是吗不一样
    git log branch1…branch2

  4. 在上述情况下,在显示出没个提交是在哪个分支上

git log –lefg-right branch1…branch2
注意 commit 后面的箭头,根据我们在 –left-right branch1…branch2 的顺序,左箭头 < 表示是 branch1 的,右箭头 > 表示是branch2的。

本地仓库和远程仓库的差异

git比较本地仓库和远程仓库的差异

1
2
3
4
5
6
7
8
# 更新本地的远程分支
git fetch origin
# 2.本地与远程的差集 :(显示远程有而本地没有的commit信息)

git log master..origin/master
# 3.统计文件的改动
# git diff <local branch> <remote>/<remote branch>
git diff --stat master origin/master

clone两种方式:ssh和http

git clone支持多种协议,除了HTTP(s)以外,还支持SSH、Git、本地文件协议等,通常来说,Git协议下载速度最快,SSH协议用于需要用户认证的场合。

git clone ssh://user@192.168.1.5:29418/cloudclass.git
git clone http://user@192.168.1.5:10001/r/cloudclass.git
git clone git://192.168.1.5/cloudclass.git

ssh: git@github.com:videojs/video.js.git
https: https://github.com/videojs/video.js.git

ssh(YX:006)

SSH是一种网络协议,用于计算机之间的加密登录。采用了公钥加密。
github配置ssh后,每次提交代码可以不用输入密码/或者新设置的密码——非账户密码;

如果clone的是https协议,每次都需要登陆github账户
### 保存用户名密码(不用每次push都输入)

1
2
3
## git保存用户名密码。主要是后面这两行,如果不想保存,则删除即可
[credential]
helper = store

## git push fatal:HttpRequestException encountered
clone完后,在bash中git push 出错‘fatal:HttpRequestException encountered.’
原因: github禁用了TLS1.0/1.1协议

截至2018年2月22日,GitHub禁用了对弱加密的支持,这意味着许多用户会突然发现自己无法使用Git for Windows进行身份验证(影响版本低于v2.16.0)。不要恐慌,有一个修复。将Git for Windows更新到最新版本(或至少v2.16.0)。
参考:git push fatal: HttpRequestException encountered

|$_PS: 又切换ssh了:git remote set-url origin git@github.com:user/hello.git

pull/push

根据remote origin url提及的方式也不一样:ssh/http(clone时会添加,不是通过clone/本地建的项目需要先添加远程仓库)
别人提交过,要先pull:远程代码和本地不一致了,需要先pull更新,然后才能提交
本地仓库不同通过clone方式建立的/新建的,pull的时候出错:没有关系的仓库;需要添加参数pull
建立关系后,以后可以不用指明分支/主机,直接 pull/push

git pull
git pull origin master –allow-unrelated-histories
git push -u origin master
第一次提交.记得第一次push前commit,否则报错:error: src refspec master does not match any
上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。
git push

git push <远程主机名> <本地分支名>:<远程分支名>
-u: 如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push。
参考:[git push参数]

cache相关/.gitignore

git rm –cache ./bin/client/release/html/_faker.min.js
(add不成功时,也可能是进入到cache中了,此方式也有效)
其它,add –all /add -A /add dir/faker.min.js 都没有用

### lock文件删除失败
rm -f xx/.git/index.lock

git push origin master

# Git 的origin和master分析

在clone完成之后,Git 会自动为你将此远程仓库命名为origin(origin只相当于一个别名,运行git remote –v或者查看.git/config可以看到origin的含义),并下载其中所有的数据,建立一个指向它的master 分支的指针,我们用(远程仓库名)/(分支名) 这样的形式表示远程分支,所以origin/master指向的是一个remote branch(从那个branch我们clone数据到本地),但你无法在本地更改其数据。

同时,Git 会建立一个属于你自己的本地master 分支,它指向的是你刚刚从remote server传到你本地的副本。随着你不断的改动文件,git add, git commit,master的指向会自动移动,你也可以通过merge(fast forward)来移动master的指向。
……
origin指定了你要push到哪个remote

master其实是一个“refspec”,正常的“refspec”的形式为”+<src>:<dst>”,冒号前表示local branch的名字,冒号后表示remote repository下 branch的名字。注意,如果你省略了<dst>,git就认为你想push到remote repository下和local branch相同名字的branch。听起来有点拗口,再解释下,push是怎么个push法,就是把本地branch指向的commit push到remote repository下的branch,比如

git push origin master:master (在local repository中找到名字为master的branch,使用它去更新remote repository下名字为master的branch,如果remote repository下不存在名字是master的branch,那么新建一个)

git push origin master (省略了<dst>,等价于“git push origin master:master”)

git push origin master:refs/for/mybranch (在local repository中找到名字为master的branch,用他去更新remote repository下面名字为mybranch的branch)

git push origin HEAD:refs/for/mybranch (HEAD指向当前工作的branch,master不一定指向当前工作的branch,所以我觉得用HEAD还比master好些)

git push origin :mybranch (再origin repository里面查找mybranch,删除它。用一个空的去更新它,就相当于删除了)

# Git 里面的 origin 到底代表啥意思?

这个时候,如果user2想加一个远程指向你的代码库,他可以在控制台输入
git remote add upstream https://github.com/user1/repository.git
然后再输入一遍 git remote -v输出结果就会变为:
origin https://github.com/user2/repository.git (fetch)
origin https://github.com/user2/repository.git (push)
upstream https://github.com/user1/repository.git (push)
upstream https://github.com/user1/repository.git (push)

增加了指向user1代码库的upstream,也就是之前对指向位置的命名。总结来讲,顾名思义,origin就是一个名字,它是在你clone一个托管在Github上代码库时,git为你默认创建的指向这个远程代码库的标签, @陈肖恩的答案并不准确,origin指向的是repository,master只是这个repository中默认创建的第一个branch。当你git push的时候因为origin和master都是默认创建的,所以可以这样省略,但是这个是bad practice,因为当你换一个branch再git push的时候,有时候就纠结了

git pull

### 配置pull 为rebase
默认:git pull = git fetch + git merge

git pull --rebase
git config --global --add pull.rebase true

1
2
3
4
5
6
7
8
# 1. 设置所有分支自动
git config branch.autosetuprebase always
git config --global branch.autosetuprebase always
### 所有新切的分支都会自动rebase,但是旧的分支不起作用,需要手动指定

# 2. 设置指定的分支自动rebase
git config branch.branchname.rebase true
### 可以给没有设置自动rebase的分支,配置上都加这一行。

git fetch

git checkout -b 本地分支名x origin/远程分支名x
采用此种方法建立的本地分支会和远程分支建立映射关系。
git fetch origin 远程分支名x:本地分支名x
需要手动checkout;不会和远程分支建立映射关系。

git branch –set-upstream-to origin/远程分支名 本地分支名

[fetch和pull的区别 001]

要讲清楚git fetch,git pull的区别必须要附加讲清楚git remote,git merge 、远程repo, branch 、 commit-id 以及 FETCH_HEAD。

  1. 【git remote】首先, git是一个分布式的结构,这意味着本地和远程是一个相对的名称。
    本地的repo仓库要与远程的repo配合完成版本对应必须要有 git remote子命令,通过git remote add来添加当前本地长度的远程repo, 有了这个动作本地的repo就知道了当遇到git push 的时候应该往哪里提交代码。
  2. 【git branch】其次,git天生就是为了多版本分支管理而创造的,因此分支一说,不得不提, 分支就相当于是为了单独记录软件的某一个发布版本而存在的,既然git是分布式的,便有了本地分支和远程分支一说,git branch 可以查看本地分支, git branch -r 可以用来查看远程分支。 本地分支和远程分支在git push 的时候可以随意指定,交错对应,只要不出现版本从图即可。
  3. 【git merge】再者,git的分布式结构也非常适合多人合作开发不同的功能模块,此时如果每个人都在其各自的分支上开发一个相对独立的模块的话,在每次release制作时都需先将各成员的模块做一个合并操作,用于合并各成员的工作成果,完成集成。 此时需要的就是git merge.
    4.【git push 和 commit-id】在每次本地工作完成后,都会做一个git commit 操作来保存当前工作到本地的repo, 此时会产生一个commit-id,这是一个能唯一标识一个版本的序列号。 在使用git push后,这个序列号还会同步到远程repo。

在理解了以上git要素之后,分析git fetch 和 git pull 就不再困难了。
首先,git fetch 有四种基本用法

  1. git fetch →→ 这将更新git remote 中所有的远程repo 所包含分支的最新commit-id, 将其记录到.git/FETCH_HEAD文件中
  2. git fetch remote_repo →→ 这将更新名称为remote_repo 的远程repo上的所有branch的最新commit-id,将其记录。
  3. git fetch remote_repo remote_branch_name →→ 这将这将更新名称为remote_repo 的远程repo上的分支: remote_branch_name
  4. git fetch remote_repo remote_branch_name:local_branch_name →→ 这将这将更新名称为remote_repo 的远程repo上的分支: remote_branch_name ,并在本地创建local_branch_name 本地分支保存远端分支的所有数据。

FETCH_HEAD: 是一个版本链接,记录在本地的一个文件中,指向着目前已经从远程仓库取下来的分支的末端版本。

git pull 的运行过程:
git pull : 首先,基于本地的FETCH_HEAD记录,比对本地的FETCH_HEAD记录与远程仓库的版本号,然后git fetch 获得当前指向的远程分支的后续版本的数据,然后再利用git merge将其与本地的当前分支合并。

撤销和回滚/版本回退

通过 git checkout – 文件名 命令可以撤销文件在工作区的修改。
通过 git reset 文件名 命令可以撤销指定文件的 git add 操作,即这个文件在暂存区的修改。
通过 git reset 命令可以撤销之前的所有 git add 操作,即在暂存区的修改。

git checkout – 文件名 命令中的 – 表示命令行在 – 之后没有更多的选项。这样的好处是,如果碰巧有一个分支与文件名重名,仍然可以恢复该文件,而不是切换到同名的分支。

没有放入暂存区(即文件一直在工作区): git checkout
放入暂存区,且文件没有再次修改(即文件已经进入暂存区): git reset; git checkout
放入暂存区,且文件再次修改:分三步 git checkout(撤销工作区的改动);git reset;git checkout

### 0
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb…上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
### 1
现在,我们要把当前版本回退到上一个版本就可以使用git reset命令:
$ git reset –hard HEAD^
### 2
然我们用git log再看看现在版本库的状态:
最新的那个版本append GPL已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?

1) 只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPL的commit id是1094adb…,于是就可以指定回到未来的某个版本:$ git reset --hard 1094a
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
2) Git提供了一个命令git reflog用来记录你的每一次命令:

### 3
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL:
然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。

### 小结
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset –hard commit_id。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

git revert 和 git reset 的区别

sourceTree 中 revert 译为提交回滚,作用为忽略你指定的版本,然后提交一个新的版本。新的版本中已近删除了你所指定的版本。

reset 为 重置到这次提交,将内容重置到指定的版本。git reset 命令后面是需要加2种参数的:–-hard 和 –-soft。这条命令默认情况下是 -–soft。

执行上述命令时,这该条commit号之 后(时间作为参考点)的所有commit的修改都会退回到git缓冲区中。使用git status 命令可以在缓冲区中看到这些修改。
而如果加上-–hard参数,则缓冲区中不会存储这些修改,git会直接丢弃这部分内容。
可以使用 git push origin HEAD –force 强制将分区内容推送到远程服务器。

默认参数 -soft,所有commit的修改都会退回到git缓冲区
参数–hard,所有commit的修改直接丢弃
推送到远程 $ git push origin HEAD --force

修改/撤销 远程的提交

撤销push

  1. 执行 git log查看日志,获取需要回退的版本号
  2. 执行 git reset –-soft <版本号> ,如 git reset --soft 4f5e9a90edeadcc45d85f43bd861a837fa7ce4c7 ,重置至指定版本的提交,达到撤销提交的目的

然后执行 git log 查看
此时,已重置至指定版本的提交,log中已经没有了需要撤销的提交

git reset 命令分为两种: git reset –-soft 与 git reset –-hard ,区别是:
   前者表示只是改变了HEAD的指向,本地代码不会变化,我们使用git status依然可以看到,同时也可以git commit提交。后者直接回改变本地源码,不仅仅指向变化了,代码也回到了那个版本时的代码。

  1. 执行 git push origin 分支名 –-force ,强制提交当前版本号。

至此,撤销push提交完成。

撤销commit

  1. 执行 git log 查看需要撤销的commit的前面一个提交版本的id;
  2. 执行 git reset –hard commit_id ,该commit_id为需要撤销的commit的提交的前面一个提交的版本,即需要恢复到的提交的id,重置至指定版本的提交,达到撤销提交的目的
  3. 执行 git log 查看,commit提交已撤销

revert和reset

注意,revert和reset的区别:
revert是放弃指定提交的修改,但是会生成一次新的提交,需要填写提交注释,以前的历史记录都在,
而reset是指将HEAD指针指到指定提交,历史记录中不会出现放弃的提交记录。

tag

分为两种:lightweight and annotated.

1
2
3
4
5
6
# 建立tag
$ git tag v1.4-lw
git tag -a v1.4 -m "my version 1.4"

# 拉新分支
git checkout -b new-br tag-version

修改标签名

1
2
3
4
5
git tag new old
git tag -d old # 删除
git push origin :refs/tags/old # 删除远程标签
git push --tags # 推送所有标签
# git push origin --tags

发行版

关于发行版: https://docs.github.com/zh/repositories/releasing-projects-on-github/about-releases
管理仓库中的发行版: https://docs.github.com/zh/repositories/releasing-projects-on-github/managing-releases-in-a-repository
发行版是可部署的软件迭代,您可以打包并提供给更广泛的受众下载和使用。
发行版基于用于标记存储库历史记录中的特定点的 Git 标记。

区别于tag

三、比较
标签是git中的概念,而release则是Github、码云等源码托管商所提供的更高层的概念。也就是说git本身是没有release这个概念的,只有tag。
两者之间的关系则是,release基于tag,为tag添加更丰富的信息,一般是编译好的文件。
四、总结
Release是源码托管商对git的tag功能的增强。通过git提供的tag功能,我们可以给项目进行版本标识,以识别特定的版本,如v0.1.0、v1.0.0等。而通过源码托管商提供的release功能,在tag的基础上我们可以添加编译好的二进制文件等,如.deb、.exe等给特定的版本提供更多的信息,方便用户,也方便后期查找特定版本的程序。

merge操作

  1. 不希望合并进去,公开 给 其他人的 文件
    1
    config.xml merge=ours

git config --global merge.ours.driver true

只有先修改的往后来修改的合并的时候才会生效。

储藏与清理

7.3 Git 工具 - 储藏与清理

现在想要切换分支,但是还不想要提交之前的工作;所以储藏修改。 将新的储藏推送到栈上,运行 git stash 或 git stash save

git stash save "messeag"

stash(Git代码冲突)

Git出现error: Your local changes to the following files would be overwritten by merge: … Please, commit your changes or stash them before you can merge.

If you want remove all local changes from your working copy, simply stash them:
1、如果希望保留生产服务器上所做的改动,仅仅并入新配置项, 处理方法如下:
git stash |git stash save –keep-index
git pull
git stash pop |git stash drop
然后可以使用Git diff -w +文件名来确认代码自动合并的情况。

2、如果要直接使用服务器上最新版本,那么可以选择直接覆盖
git reset –hard
git pull
其中git reset是针对版本。,如果想针对文件回退本地修改,使用
git checkout HEAD file/to/overwrite
git pull

If you want to overwrite only specific parts of your local changes, there are two possibilities:
1. Commit everything you don’t want to overwrite and use the method above for the rest.
2. Use git checkout path/to/file/to/revert for the changes you wish to overwrite. Make sure that file is not staged via git reset HEAD path/to/file/to/revert.

找回丢失的stash

git-fsck

由于git stash pop恢复的同时把stash内容也删掉, 所以stash list不再会有之前的stash。
但是git stash pop出的change是可以找回的,因为每次git stash都会生成一个新的commit,只要知道commitID, 通过git stash apply commitID 就可以应用之前的stash

寻找commitID有两种方法:
1、git stash pop 最后会打印出pop掉的commitid值,若这个记录还存在直接使用即可。
2、git fsck –lost-found, 会打印出所有dangling commit,
这里面大概有三种类型的内容,blob、tree和commit。
但是这些id所对应的记录并不是有序的,如果想要找到之前误删的内容,需要我们一条条的去show出这些内容,然后判断是否是要找回的。
可以关注以下两点内容,快速找出你需要的commitId:
(1)修改内容
(2)日期
找到commitID之后就去执行git stash apply commitID恢复你的工作区吧~

1
2
3
4
$ git fsck --lost-found
$ git show commitId
$ git stash apply commitID
# git merge + id

clean

git clean -d -fx “”
其中
x —–删除忽略文件已经对git来说不识别的文件
d —–删除未被添加到git的路径中的文件
f —–强制运行

rebase

在rebase的过程中,也许会出现冲突(conflict)。在这种情况,Git会停止rebase并会让你去解决冲突;在解决完冲突后,用”git add“命令去更新这些内容的索引(index), 然后,你无需执行 git commit,只要执行:
$ git rebase --continue
这样git会继续应用(apply)余下的补丁。
在任何时候,可以用–abort参数来终止rebase的操作,并且”mywork“ 分支会回到rebase开始前的状态。
$ git rebase --abort

合并两条commit记录

合并两条commit记录git rebase -i HEAD~2
(i的意思是:interactive,HEAD~2为在历史的前两个提交,同理,HEAD~4就是历史的前四个提交。)

将第二行的pick改成s, 也就是squash(挤压合并),作用是:使用提交,将此提交与之前的提交合并。 然后保存文件退出vim。
将之前的两条提交描述信息,修改合并为一条,然后保存退出vim

git rebase 遇到的问题

rebase 后推送不成功

解决办法

1) feature分支只有你一个人在开发
此时没有其他人会进行提交操作,那么可以直接进行强制推送 git push --force origin feature ,–force可以直接理解为用你本地分支的状态区覆盖掉远端origin分支的状态,也就是执行过后,本地的分支什么样,远端分支就什么样
2) feature分支有多人开发
此时如果你贸然的使用–force命令,会有覆盖掉其他人提交代码的风险。比如,小明和小红两个人同时在feature分支上进行开发,小明已经在feature分支上提交了一部分代码,而小红此时执行了rebase操作,所以如果想要推送到远端仓库就必须使用 - -force 参数,而小红推送成功之后就会覆盖掉小明提交的代码(前面说过–force就是用本地状态覆盖掉远端状态)。在这种情况下,推荐另外一种更安全的命令 git push --force-with-lease origin feature 使用该命令在强制覆盖前会进行一次检查如果其他人在该分支上有提交会有一个警告,此时可以避免福改代码的风险

重置密码

Git提供一个内置的凭证系统,这个系统是Git原生实现的,只需要安装了Git就可以使用,该系统提供两种模式(cache和store)

1
2
3
4
git config --global credential.helper

git config --global credential.helper cache
git config --global credential.helper store

提交用户名修改

1)如果本地只有一个待push的commit:

$ git commit --amend --reset-author

使用git log确认当前commit的Author信息已经重置

2)如果本地有多个待Push的commits,解决方案如下:

  • git soft reset到之前的版本重新提交;
    或者
  • 暂时关闭设置中的提交检查,提交后再打开(不建议)

清空提交记录

清除git仓库的所有提交记录,成为一个新的干净仓库

1
2
3
4
5
6
git checkout --orphan latest_branch
git add -A
git commit -am "commit message"
git branch -D master
git branch -m master
git push -f origin master

对于–orphan < new_branch > 的解释就是:

Create a new orphan branch, named <new_branch>, started from
<start_point> and switch to it. The first commit made on this new
branch will have no parents and it will be the root of a new
history totally disconnected from all the other branches and
commits.

The index and the working tree are adjusted as if you had
previously run “git checkout <start_point>“. This allows you to
start a new history that records a set of paths similar to
<start_point> by easily running “git commit -a” to make the root
commit.

添加多个远程仓库

# git 本地项目添加多个远程仓库
第一种方式:

  1. 添加一个远程库 名字不能是origin
    git remote add 17MOX http://git.17byh.com/17MOX/mxhy.git
  2. 拉,推
    git pull 17MOX 远程分支名:本地分支名
    git push 17MOx 本地分支名:远程分支名

第二种方式:(好处时,推送时,可以同时推送到另外一个库)

  1. 添加另外一个远程库
    git remote set-url –add origin git@gitlab.com:mzc/DIVIDE_PKG.git
    git push origin master:master

# Git 怎么添加多个远程仓库呢?
可以通过-all一次提交多个仓库
配置远程仓库
git remote add origin https://url
再添加一个远程仓库
git remote set-url –add origin https://url

注意这里多次添加需要用
git remote set-url –add
不然会报错:fatal: remote origin already exists.
PS: 这里是上文提到的第二种方式,同时提交
或者改名
git remote add otherOrigin https://url

一次提交到所有远程仓库
git push –all

注意
git pull 是 git pull (from) origin (to) master
git push 是 git push (to) origin (from) master

配置多个仓库,想提交不同的gitignore

1) 新建分支,修改.gitignore, 删除文件等其他修改。 缺点: 每次都要修改许多文件,然后才可以提交,有些繁琐。
2) git rm -r –cached
将.setting文件夹从版本库中删除
git rm -r –cached .setting #–cached不会把本地的.setting删除
git commit -m ‘delete .setting dir’
git push -u origin master

将被.gitignore文件所忽略的文件从版本库中删除
git rm -r –cached .
git add .
git commit
git push -u origin master

用 git rm 来删除文件,同时还会将这个删除操作记录下来;
用 rm 来删除文件,仅仅是删除了物理文件,没有将其从 git 的记录中剔除。

直观的来讲,git rm 删除过的文件,执行 git commit -m “abc” 提交时,会自动将删除该文件的操作提交上去。

而用 rm 命令直接删除的文件,单纯执行 git commit -m “abc” 提交时,则不会将删除该文件的操作提交上去,需要在执行commit的时候,多加一个-a参数,
即rm删除后,需要使用git commit -am “abc”提交才会将删除文件的操作提交上去。

问题

配置

core.autocrlf

warning: LF will be replaced by CRLF in ******
git config core.autocrlf false (仅对当前git仓库有效)
git config –global core.autocrlf false (全局有效,不设置推荐全局)

git config –global core.autocrlf input
git config –global core.safecrlf warn

LF和CRLF其实都是换行符,但是不同的是,LF是linux和Unix系统的换行符,CRLF是window 系统的换行符。这就给跨平台的协作的项目带来了问题,保存文件到底是使用哪个标准呢?
git为了解决这个问题,提供了一个”换行符自动转换“的功能,并且这个功能是默认处于”自动模式“即开启状态的。
这个换行符自动转换会自动把你代码里 与你当前操作系统不相同的换行的方式 转换成当前系统的换行方式(即LF和CRLF 之间的转换),这样一来,当你提交代码的时候,即使你没有修改过某个文件,也被git认为你修改过了,从而提示”LF will be replaced by CRLF in *

PS: 编辑器可以设置。

core.ignorecas

Git配置默认忽略了大小写。 修改大小写后,提交不到git仓库。比如Debug 改为debug,远端没有变化。

1
2
3
4
5
6
7
# 修改默认设置
git config core.ignorecase false
# 推荐
git mv -f test.js Test.js
# 最次
git rm DataExt.java
git add Dataext.java

git remote: HTTP Basic: Access denied

原因:远程服务端的用户名和密码与当前系统中git保存的用户名和密码有冲突
git config –system –unset credential.helper命令,作用就是清空本地保存的用户名和密码
但后面发现每次操作远程仓库都需要重新输入用户名和密码,这个命令清空gitconfig里的自动保存用户名和密码配置,找到本地的gitconfig文件,写入:
如果不想保存,则删除即可

1
2
[credential]
helper = store

可能原因是在远端/浏览器修改了密码,而本地存储的仍是就密码不一致。
可以删除(网站)用户凭证(window;mac好像没成功)。

18:52

工具

sourceTree

破解: 需要认证时退出,修改以下文件后,重新启动。
C:\Users\xxxxx\AppData\Local\Atlassian\SourceTree\account.json
C:\Users\xxxxx\AppData\Local\Atlassian\SourceTree.exe_Url_1kidzh22pwslluf1rgjympiqlohmf5ps\3.1.3.3158\user.config

knowledge is no pay,reward is kindness
0%