很多人会用 Git 提交代码,却卡在“怎么把本地项目放到 GitHub,并让别人一起协作”这一步。这个练习的核心不是背命令,而是走完整条链路:本地 Python 项目、远程仓库、首次推送、分支协作、拉取更新。
本地项目先要像个项目
在推到 GitHub 之前,本地目录最好已经具备最小的项目结构。哪怕只是一个练习项目,也应该有入口文件、依赖说明、忽略规则和 README。这样别人 clone 下来以后知道怎么运行,也不会把虚拟环境、缓存文件一起推上去。
可以这样实践,创建一个最小 Python 项目:
mkdir github-python-demo
cd github-python-demo
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
cat > app.py <<'PY'
def greet(name: str) -> str:
return f"Hello, {name}!"
if __name__ == "__main__":
print(greet("GitHub"))
PY
cat > README.md <<'MD'
# github-python-demo
A tiny Python project used to practice pushing code to GitHub.
## Run
```bash
python app.py
MD
cat > .gitignore <<'EOF' .venv/ pycache/ *.pyc .env EOF
python app.py
运行前需要确认本机已安装 Python 3。Windows PowerShell 激活虚拟环境的命令通常是:
```bash
.venv\Scripts\Activate.ps1
初始化 Git,并准备第一次提交
GitHub 是远程托管平台,Git 是本地版本控制工具。推送之前,本地仓库必须先有提交记录。
git init
git status
git add app.py README.md .gitignore
git commit -m "Initial Python project"
如果这是你第一次在机器上使用 Git,可能还需要配置身份:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
这里的邮箱建议使用你 GitHub 账号关联的邮箱,或者 GitHub 提供的 noreply 邮箱。协作时,提交记录里的身份会影响别人追踪变更来源。
连接 GitHub 远程仓库并推送
在 GitHub 上创建一个空仓库后,不要勾选自动生成 README、license 或 .gitignore,这样可以避免第一次推送时出现无关冲突。假设远程仓库地址是 https://github.com/YOUR_NAME/github-python-demo.git,把 YOUR_NAME 改成你的 GitHub 用户名或组织名:
git branch -M main
git remote add origin https://github.com/YOUR_NAME/github-python-demo.git
git push -u origin main
-u origin main 会建立本地 main 分支和远程 origin/main 的跟踪关系。之后日常推送可以简化成:
git push
如果你使用 SSH,也可以把远程地址换成:
git remote set-url origin git@github.com:YOUR_NAME/github-python-demo.git
验证远程配置:
git remote -v
git log --oneline --decorate --graph --all
协作不是直接往 main 上堆代码
多人协作时,常见做法是每个改动开一个分支,通过 Pull Request 讨论和合并。这样 main 分支保持稳定,代码审查、测试和回滚都有清晰边界。
可以这样模拟一次协作修改:
git checkout -b feature/add-cli-name
python - <<'PY'
from pathlib import Path
p = Path("app.py")
p.write_text('''import sys
def greet(name: str) -> str:
return f"Hello, {name}!"
if __name__ == "__main__":
name = sys.argv[1] if len(sys.argv) > 1 else "GitHub"
print(greet(name))
''')
PY
python app.py Ada
git add app.py
git commit -m "Allow greeting a custom name"
git push -u origin feature/add-cli-name
推送后,在 GitHub 页面上创建 Pull Request,请同伴 review。合并后,本地同步主分支:
git checkout main
git pull --ff-only origin main
git branch -d feature/add-cli-name
--ff-only 的好处是:如果远程历史不能快进合并,Git 会停下来让你处理,而不是自动制造一个你没预期的合并提交。
常见坑:认证、冲突和忽略文件
GitHub 现在不建议用账号密码直接推送 HTTPS 仓库,通常需要 Personal Access Token,或者改用 SSH key。遇到认证失败时,不要反复改代码,先确认远程地址和认证方式。
另一个高频问题是把不该提交的文件推上去,例如 .venv/、.env、缓存目录。如果已经提交过敏感信息,仅仅删除文件再提交不等于从历史中清除;这时要轮换密钥,并用专门的历史清理工具处理。
冲突则是协作里的正常事件。处理顺序很简单:拉取最新代码、打开冲突文件、保留正确内容、重新测试、再提交。
git pull origin main
# 编辑出现冲突的文件,删除 <<<<<<< ======= >>>>>>> 标记
python app.py Test
git add app.py
git commit
采用清单
把 Python 项目放到 GitHub,不只是“能 push 上去”。更稳妥的检查清单是:
- 仓库里有
README.md,别人知道如何运行项目。 .gitignore排除了虚拟环境、缓存和本地密钥。- 默认分支使用
main,本地分支跟踪远程分支。 - 新功能走独立分支和 Pull Request。
- 合并前至少运行一次项目或测试命令。
- 不把 token、密码、
.env文件提交到仓库。
练习题的价值在于把这些动作连起来。真正掌握 GitHub,不是记住某个按钮在哪里,而是知道代码从本地变成团队资产的每一步发生了什么。