解决git无法push的问题

背景

5月16日,也就是前天,我开始学习李辉的Flask入门教程

目的很简单,由于花了一周时间学习Miguel Grinberg的The Flask Mega-Tutorial,在第四章“Database”上的时间有将近3天。我感觉自己的进度有些快,步子太大,终于扯到了。

按照推特上这位大神的说法,要享受海洋般的码农的工作机会,要经历9层磨难:Flask是第7层,Database是第8层。

wecom-temp-90ebe03d8c5e0ab68eda5686bd5102e9

在第8层滞留许久后,我开始采用李辉的教程,这个教程恰好与Miguel Grinberg的教材在部分知识点上互补。比如【Mega-Tutorial】介绍使用git时,仅仅介绍了git clone命令,方便读者不用逐行敲代码,而【Flask入门教程】对git的介绍就更实用,从git repo的建立开始,包括如何管理自己的git hub页面。

使用git完成watchlist项目后,依葫芦画瓢,我在microblog的项目上也使用了类似命令,但是问题就发生了:

22-05-18/Users/xxxxx/study/test~%>git branch -a
*flask
master

似乎自己就被困在了【Mega-Tutroial】的怪圈里,我估计原因是使用git clone后,默认的分支就是flask,而不是自己新建的master分支,而且无法删除flask这个主分支。

最直接的办法,是新建了一个test目录,在这个目录下把所有文件拷贝到flasktest下面,对原来的内容覆盖掉。

cp -rf flasktest/. test

然而,除了主branch变成master外,一切照旧。

问题现象与分析

现象

我开始就认为是权限问题,“access rights”。

22-05-18/Users/XXXXX/study/flasktest~%>git pull
ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

所以把努力方向放在如何优化授权上面,比如把私钥再增加一次:

ssh-add ~/.ssh/id_rsa
22-05-18/Users/XXXXX/study/flasktest~%>ssh-add -l
3072 SHA256:n9EHVCpvMuEfdkajdfkajfdkjakdfjakjdfak//Q5pbok XXXXXXXX@dfjakjdfjdfajdfa (RSA)

分析

由于告警信息中也出现了“no work tree”,网上有类似分析说这是bare repository:
The direct reason for the error is that yes, it’s impossible to use git-add with a bare repository. A bare repository, by definition, has no work tree. git-add takes files from the work tree and adds them to the index, in preparation for committing.
尝试去除bare:

git config --unset core.bare

也有意见说,在git的配置文件里,把origin相关信息都屏蔽掉:

22-05-18/Users/xxxxxxxxx/study/test/.git~%>vi config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
#[remote "origin"]
#       url = git@github.com:xxxxxxxx/flasktest.git
#       fetch = +refs/heads/*:refs/remotes/origin/*
#[remote "origin"]
#       url = git@github.com:xxxxxxxx/flasktest.git
#       fetch = +refs/heads/*:refs/remotes/origin/*
[remote "origin"]
        url = git@github.com:xxxxxxxxx/flasktest.git
        fetch = +refs/heads/*:refs/remotes/origin/*

问题解决

折腾了2天,最后只能盯着屏幕告警,突然发现“and the repository exists”,这句话提醒我,是不是这个repo根本就没有创建成功过?

立即上github,手动创建repo。

然后一切水到渠成

22-05-18/Users/xxxxxx/study/flasktest~%>git branch -a
* master
  remotes/origin/master

反思

  1. 想当然认为,repo是通过git命令行来建立的,因此不断的假设flasktest.git已经建立好了;
  2. 并没有认真对待git,git的培训教程也没有认真学习。

git培训教材

Git

基本操作

绑定用户名和邮箱地址

(venv) 22-05-17/Users/XXXXX/study/watchlist~%>git --version
git version 2.30.1 (Apple Git-130)
(venv) 22-05-17/Users/xxxxx/study/watchlist~%>git config --global user.nam
e "xxxxxxx"
(venv) 22-05-17/Users/xxxxx/study/watchlist~%>git config --global user.ema
il "xxxxxx@outlook.com"

查看本地分支

test~%>git branch -vv
* flask     71a338f this is a test of microblog project
  flasktest 71a338f this is a test of microblog project
  master    71a338f this is a test of microblog project

查看远程分支

watchlist~%>git branch -r
  origin/master

删除本地分支

microblog/test~%>git branch -d flasktest
Deleted branch flasktest (was 71a338f).

查看配置列表

test~%>git config --list
remote.origin.url=git@github.com:XXXXXX/flasktest.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin

push与pull

push命令

push命令用来将远程分支内容,拉取到本地分支上,当远程分支和本地分支名称一致时,可以省略本地分支名称,push命令中的origin会让人很疑惑

pull命令

push与pull命令参考

建立或删除本地库与远程库的绑定

建立本地库与远程库的绑定关系,和远程库进行绑定时,需要给远程库一个名字,一般来说origin就是默认的名称

xxx/flasky/watchlist~%>git remote add origin git@github.com:xxx/watchlist.git

删除本地库和远程库的绑定,注意这里只是删除了本地库与远程库之间的映射关系,并没有真的删除任何物理内容。

xxx/flasky/watchlist/watchlist~%>git remote rm origin
xxx/flasky/watchlist/watchlist~%>git remote -v

如果有绑定的远程库,命令“git remote -v”会显示如下

现在因为我使用git remote rm origin命令删除了绑定关系,则git remote -v什么都不会显示,因为linux的最大理念就是,“没有消息就是好消息”😊

fatal: refusing to merge unrealated histories

xxxx/flasky/watchlist~%>git pull origin master
From https://github.com/xxxx/watchlist
 * branch            master     -> FETCH_HEAD
fatal: refusing to merge unrelated histories

The “fatal: refusing to merge unrelated histories” Git error occurs when two unrelated projects are merged, and two projects are unaware of each other existence and having mismatch commit histories.

To provide a little background .git directory, which is usually hidden, contains all the changes or “commits” of the repo that gets tracked. Rewriting the repository history is possible, but it’s generally not the typical use case. Git is used for version control, which means to track the history of the file.

Use Cases that lead to git fatal: refusing to merge unrelated histories

If you have cloned a repository and, for some reason, the .git folder is corrupted or deleted. Since git will be unaware of your local history, any action you perform like git pull or git push to remote repository will throw this error as there is no tracking information for the current branch.
You have created a new repository, made few commits to it, and now try to pull a remote repository that already has its own commits. Git will throw an error here since it is unaware of how these two projects and commits are related.

The solution to Refusing to merge unrelated histories

The error started occurring from git version 2.9.0 release notes and above. To solve this issue –allow-unrelated-histories flag when pulling the data from remote repository.

解决unrelated histories问题参考

全流程概要

  • 1 绑定用户名和邮箱地址(SSH指纹也提前关联好)
  • 2 mkdir watchlist
  • 3 初始化本地库
xxxx/flasky/watchlist~%>git init
Initialized empty Git repository in /Users/xxxx/Study/flasky/watchlist/.git/
  • 4 绑定本地库与远程库
flasky/watchlist~%>git remote add origin git@github.com:madapapa/watchlist.git
  • 5 查看远程库
xxxx/flasky/watchlist~%>git remote -v
origin	git@github.com:madapapa/watchlist.git (fetch)
origin	git@github.com:madapapa/watchlist.git (push)
  • 6 同步远程库内容,忽略unrelated histories问题
xxxx/flasky/watchlist~%>git pull origin master --allow-unrelated-histories
remote: Enumerating objects: 49, done.
remote: Counting objects: 100% (49/49), done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 49 (delta 16), reused 38 (delta 10), pack-reused 0
Unpacking objects: 100% (49/49), 438.70 KiB | 477.00 KiB/s, done.
From github.com:madapapa/watchlist
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
  • 7 我没有新建gitignore文件

  • 8 在本地修改文件后,进行提交工作

【注意】这里的push命令在第一次使用时,一般建议附带-u参数,这样Git不仅会把本地master分支的内容更新到远程新建的master分支上,还会把本地master和远程的master关联起来,在以后的推送和拉取时就可以简化命令(不需要带-u参数,直接git push即可)。

git常用命令

折腾苹果电脑的zsh

早晨看miguel grinberg的视频,发现他用的iterm2挺好看。然后打开自己的iterm2进行配置,说实话只是简单的配置了绿色字体,但是提示符是没法通过profile来修改的。

随后的2个小时,就是用来折腾zsh,今天算是有了心得。

首先是,修改zshrc的权限(MDMacpro这台电脑)

chmod 666 zshrc

然后修改zshrc

下面是更改颜色,其中省略号部分,全部会改成期望的颜色(这里是蓝色,12,也可以用blue来替代–但是我没有尝试)

%F{12}......%f

%D代表日期(年月日) %d代表当前目录。

非常简洁,而且iterm和terminal的界面会同时更改。

我的另外一台电脑(工作电脑),用了oh my zsh,只要使用

opebn ~/.zshrc

把ZSH_THEME注释掉,就可以使用PS1的方式来修改提示符了。

Python里的__name__究竟有啥用

由于在Pyhton里,并没有一个类似c或其他语言的main()函数,所以当我们把运行python程序的命令传递给所谓解释器,如CPython,或更常见的基于BSD开发的交互式解释器IPython。

比如,使用flask框架进行web编程:

export FLASK_APP = test1.py

通常,解释器会按照第一个没有缩近的代码来顺序执行。
不过,在执行前,解释器会定义一些特殊的变量,__name__就是这种变量。

如果被执行文件是自己被直接执行,那么解释器就会将__name__设置为__main__;如果被执行文件是被import的,那么__name__就会被设置为导入的模块名。

通过对__name__ 变量的检查,我们就可以知道被执行文件是否是被导入的。

下面举个例子:
一个test1.py的文件

print("test1 __name__ is %s"   %__name__)
if __name__ == "__main__":
    print("test1 is being run directly")
else:
    print("test1 is being imported")

输出结果如下

(venv) *****microblog/test/test1.py
test1 __name__ is __main__
test1 is being run directly

test2.py的文件

import test1

print("test2 __name__ is %s " %__name__)

输出结果如下

(venv) *****/microblog/test/test2.py
test1 __name__ is test1
test1 is being imported
test2 __name__ is __main__ 

flask小技巧

“(venv) $ export FLASK_APP=hello.py
(venv) $ export FLASK_DEBUG=1
(venv) $ flask run”

如下,当设置debug为1,允许reloader和debug两种模式,在reloader模式下,程序会自动检测code里的修改,非常方便的功能。

“(venv) $ flask run --help
Usage: flask run [OPTIONS]

  Runs a local development server for the Flask application.

  This local server is recommended for development purposes only but it can
  also be used for simple intranet deployments.  By default it will not
  support any sort of concurrency at all to simplify debugging.  This can be
  changed with the --with-threads option which will enable basic
  multithreading.

  The reloader and debugger are by default enabled if the debug flag of

Options:
  -h, --host TEXT                 The interface to bind to.
  -p, --port INTEGER              The port to bind to.
  --reload / --no-reload          Enable or disable the reloader.  By default
                                  the reloader is active if debug is enabled.
  --debugger / --no-debugger      Enable or disable the debugger.  By default
                                  the debugger is active if debug is enabled.
  --eager-loading / --lazy-loader
                                  Enable or disable eager loading.  By default
                                  eager loading is enabled if the reloader is
                                  disabled.
  --with-threads / --without-threads
                                  Enable or disable multithreading.
  --help                          Show this message and exit.”

Git 小技巧

获取第二章的sample代码

git checkout v0.2

从0.1切换到0.2时,出现如下告警

git checkout v0.2
error: Your local changes to the following files would be overwritten by checkout:
        app/routes.py
Please commit your changes or stash them before you switch branches.
Aborting

我选择放弃本地修改,切换到其他章节的代码,还有几种备选方案,可以看参考。

git reset --hard
HEAD is now at 23b3fc8 Chapter 1: Hello, World! (v0.1)
(venv) XXXXXX microblog % git checkout v0.2
Previous HEAD position was 23b3fc8 Chapter 1: Hello, World! (v0.1)
HEAD is now at 5d45592 Chapter 2: Templates (v0.2)

参考

you have three options:

Commit the change using
git commit -m "My message"
Stash it.
Stashing acts as a stack, where you can push changes, and you pop them in reverse order.

To stash, type

git stash
Do the merge, and then pull the stash:

git stash pop
Discard the local changes
using git reset --hard
or git checkout -t -f remote/branch

Or: Discard local changes for a specific file
using git checkout filename

解决公司电脑无法更新问题

公司发的mac book,是m1芯片,但因为数据安全问题,对于部分权限做了限制,如:无法进行系统更新,需要拿到it部门解决。

前几天我打算重启python编程训练,发现无法安装numpy。

过了两天,灵机一动,在虚拟环境下,venv里进行安装

首先激活虚拟环境

 . venv/bin/activate

然后,在虚拟环境下更新pip

  python -m pip install --upgrade pip
  Requirement already satisfied: pip in ./venv/lib/python3.8/site-packages (22.0.4)

最后,安装numpy

  pip3 install numpy  
  Requirement already satisfied: numpy in ./venv/lib/python3.8/site-packages (1.22.3)

退出虚拟环境

  deactivate