git踩坑指南

git踩坑指南

1.一些简介

git是一个分布式的代码管理仓库:

  • 本地和远程上都有独立的库,可以用push命令远程提交
  • 会保存完整的代码提交记录,每一次提交的都是文件快照
优势 劣势
对团队合作非常友好 大文件的支持度不太好(可以用git-lfs补足),因为每一次git提交都占用库存

2.一些命令

2.1.初始化

# 本地项目初始化,在工作区根目录下
git init

[--initial-branch] 初始化的分支

[--bare] 创建一个裸仓库,只有git目录、无工作目录

[--template] 用模板创建提前构建好的自定义git目录

初始化会创建.git配置文件夹,部分配置文件夹如下:

  • objects:存放加密文件快照(在暂存区)

    1. git cat-file -p file_id可以查看文件内容,file_id = 文件夹名+文件名(就是那一串字符)
    2. 会有一个目录树文件,放着所有文件id、名字
    3. commit注释文件
    4. 查找顺序是:commit文件(会存储对应的tree id)->tree信息->code文件
  • refs:当做一个指针

    1. heads:分支。文件夹cat .git/refs/heads/master,会看到当前ref版本下master对应的commit id

    2. tags:标签(意味着稳定版本)。通过git tag tag_name生成

      annotation tag:附注标签,说明这个版本的特色,`git tag -a v0.2 -m "add new function"

git的配置有三个级别:低级别的配置会覆盖高级别的配置

  1. --global,全局
  2. --system,系统
  3. --local,本地

2.2.remote

# 查看remote源
git remote -v 
  • 同一个origin设置不同的push和fetch url

    git remote add git@url1.git
    git remote set-url --add --push origin git@url2.git
    
  • 可以经常cat .git/config查看仓库remote配置

2.2.1.HTTP remote

免密配置:

# 内存
git config --global credential.helper `cache --timeout=3600`
# 硬盘,不指定则默认路径为~/.git-credentials
git config --global credential.helper "store --file /path_to_credential"  

信息的格式:${scheme}://${user}:${password}@github.com

2.2.2.SSH remote

默认使用的rsa,但是安全问题的话,现在优先用ed25519

ssh-keygen -t ed25519 -C "your-github-email@com"
  • 需要有""
  • [-t],选择秘钥类型

2.3.parent commit

更新文件后,tree会更新为最新版本,同时出现一个parent信息,指向之前的版本

2.3.1.修改历史版本

  1. commit --amend:修改后commit id会变
  2. git rebase -i HEAD~3修改最近三个commit:合并commit->修改具体的commit message->删除某个commit
  3. filter --branch:指定删除已提交中的某个文件or全局修改邮箱地址……

2.4.垃圾回收

  • git gc:删除没有ref指向的commit,还会对object进行一定的打包压缩->减少仓库体积
  • reflog:(回收站)记录操作日志,可以找回丢失的数据。git gc也没完全删掉多的commit,用reflog把那些日志设置为过期才算
  • git gc prune=now:指定修剪多久前的对象,默认为两周

2.5.pull & fetch

  • pull:把远程的分支拉取到本地,使远程的更新和本地同步(可能存在冲突,需要解决)

    git pull = git fetch + git merge
    git pull --rebase = git fetch + git rebase
    
  • fetch:拉取远程分支到本地,不进行merge(意思是,把远端的分支拉取到本地了,但是没有进行分支合并,这时候查看历史记录会发现远程仓库的和本地的记录不一样)。会修改refs/remote里分支信息

关于冲突:

  1. 本地commit和远端commit历史记录不同,则产生冲突(git commit --amend或者git rebase可能导致)
  2. 某分支为个人使用,或者和同组的人确认过可以修改历史,就git push origin master -f强制推送(不推荐主分支搞这个,一般先解决冲突再push)

2.6.push

git push origin master

把本地origin源的master分支推送到远程仓库里

  • origin,源的名字:.git/refs/remotes/origin

3.关于报错

You've successfully authenticated, but GitHub does not provide shell access.

如果你是用仓库的http地址进行链接的,可以不管它!只要显示了Hi,bisa!这种话就说明你远程链接仓库成功了,但你要是想push通过这个链接push代码上去,推荐采用ssh进行连接

采用ssh包括两个方面:

  1. 让你本地机生成ssh密钥,和github账号上new ssh(建立链接)<搜索关键词:“GitHub配置ssh”>
  2. 本地链接你remote的仓库时,用git remote add origin git@github.com:巴拉巴拉(也就是用仓库的ssh地址进行remote),这一步成功是不进行提示的

如果你已经设置了http的链接,现在执行git remote add origin git@...报错error: remote origin already exists. 不要担心,这个意思是说你当前本地仓库中已经在链接一个远程仓库,重新设置就行。只要执行:

git rm remote origin

git remote add origin git@...就行

error: failed to push some refs to 'github.com:巴拉巴拉'

在执行git push -u origin master时,报错提示:

 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'github.com:bisa42/learnOSTEP.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

看到它推荐我们在push前先pull一遍代码,这很可能是因为当你与其他人合作共同写一份仓库的时候,其他人对这个仓库做了改动,但你的本地库没有更新其他人的操作,此时你直接将自己的本地库push到github上,就有几率损坏别人的更新。(当你用两个机子更新同一个仓库也会如此,即使这俩机子都由你本人操作&&机子中的本地库内容相同)

可以通过下面的命令来解决(这里的master只是仓库的分支名,请更换成你的分支):

git pull origin master

fatal: Need to specify how to reconcile divergent branches.

如果你跟我一样是个倒霉蛋,在执行了上面的命令后又出现了新的问题,那先喝口水冷静一下,查看报错信息:

 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint:   git config pull.rebase false  # merge (the default strategy)
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

事实上,在这些报错出现之前,我能看到它还是成功更新了在缓存区中的文件,只不过还有点小问题罢了

image-20220922123530122

报错信息的翻译:

提示:您有不同的分支,需要指定如何协调它们。
提示:您可以通过在之前某个时间运行以下命令之一来做到这一点
提示:你的下一招:
提示:
提示:git config pull.rebase false 	# 合并(默认策略)
提示:git config pull.rebase true  	# Rebase
提示:git config pull.ff only	 	# 仅快进
提示:
提示:可以将“git config”替换为“git config——global”来设置默认值
提示:首选所有存储库。你也可以传递——rebase,——no-rebase,
提示:或命令行上的——ff-only,以覆盖配置的默认per
提示:调用。
fatal:需要指定如何协调不同的分支。

本来我要做的就是一个小仓库,并不需要考虑分支问题,所以我先尝试了提示中的默认策略:

git config pull.rebase false

结果此路不通。

当我再一次尝试git push -u origin master时,得到下面的报错:

To github.com:bisa42/learnOSTEP.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'github.com:bisa42/learnOSTEP.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

翻译:

提示:更新被拒绝,因为您当前分支的尖端位于其远程分支的后面
提示:推荐在push代码前使用类似于git pull的命令

好吧,我们现在要恢复一下分支状态(估计是因为合并分支前pull的,但现在的分支已经被我合并<pull.rebase false>了)

先查看一下最近3次的commit版本

git log -3

选择自己想回退到的commit,执行:

git reset --hard yourcommit

image-20220922125246548

fatal: refusing to merge unrelated histories

哈哈没想到吧,这是第三关!如果你进行了上面的操作,发现自己还是不能成功的git pull origin master,并且报错形如这个小标题,那么可以执行

git pull origin master --allow-unrelated-histories

这个问题可能会被翻译成“拒绝合并不相关的历史”。其实它是说你的分支(或者是两个库)没有建立过关系,在push/pull/merge的时候都可能会出现,但解决都是一个思路->加上--allow-unrelated-histories

退出编辑commit的界面

commit用的是nano文本编辑器,修改完成后按ctrl+x,再敲个大写Y,然后回车就能做到保存退出

切换成vim

什么?不想要这个编辑器?那就git config --global core.editor vim来换成vim吧~


可怕的是这篇文竟然、、<未完待续>!

posted @ 2022-09-22 13:10  比萨在哭  阅读(1353)  评论(0编辑  收藏  举报