Skip to content
分类目录:

Git

Post date:
Author:
Number of comments: no comments

https://docs.microsoft.com/en-us/azure/devops/repos/git/command-prompt?view=azure-devops

参考资料:

Beginning Git and GitHub

git command --help

Setting up git after installation

https://docs.github.com/zh/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-personal-account/managing-multiple-accounts

https://docs.github.com/zh/get-started/getting-started-with-git/setting-your-username-in-git

本地Repo中的Git用户名和Github的用户名不同,Git使用本地配置的用户名将提交和Github的身份关联。

# 1.查看git配置信息
$ git config --list

# global config
# config will be saved in the dir: C:Users\Username\.gitconfig
# git config命令的–global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

# 设置git用户名、密码、邮箱的配置(全局配置)
$ git config --global user.name 用户命
$ git config --global user.name freedom
$ git config --global user.password 密码
$ git config --global user.password abc0506abc
$ git config --global user.password 邮箱
$ git config --global user.email "154...68@qq.com"


# local config 
# 查看git用户名、密码、邮箱的配置
$ git config user.name
$ git config user.password
$ git config user.email

# 设置git用户名、密码、邮箱的配置
$ git config user.name "freedom"
$ git config user.password "123456"
$ git config user.email "154...8@qq.com"


git config credential.helper store
git config --global credential.helper 'cache --timeout 7200' # 秒

#  Windows环境下,Filename too long
git config --global core.longpaths true

无法存储登陆信息:

在.git文件夹中,打开config文件,输入以下指令

[credential]
	helper = store

或者在Windows的凭据管理中设置相关信息

SSH:

$ ls -al ~/.ssh
# Lists the files in your .ssh directory, if they exist

$ ssh-keygen -t ed25519 -C "your_email@example.com"

$ eval "$(ssh-agent -s)"
> Agent pid 59566

$ ssh-add ~/.ssh/id_ed25519

create git repository:

mikdir newproject
cd newproject
git init

.git folder content:

HEAD File: points to the current ‘branch’ or subversion of the project that you are working on. The default branch is called master ,but it is just like any other branch; Tshe name is just on old convention.

master branch is the default name for the only branch created on the repository initialization.

master 分支是初次创建仓库的分支的名称

Working Directory:

newproject directory except .git is called working directory;

use ‘git status’  to check the file status

git status
Git Basic
CommandComment
$ git init# Initial a new git database
$ git clone# Copy an existing database
$ git status# Check the status of the local project
$ git diff# Review the changes done to the project
$ git add# Tell Git to track a changed  file
$ git commit# Save the current state of the project to database
$ git push# Copy the local database to a remote server
$ git pull# Copy a remote database to a local machine
$ git log# Check the history of the project
$ git branch# List, create or delete branches
$ git merge# Merge the history of two branches together
$ git stash# Keep the current changes stashed away to be used later

Git WorkFlow:

# clone project from remote server
git clone https://github.com/TortoiseGit/TortoiseGit.git
# create a branch from master
git branch new_branch_name
#checkout the created branch
git checkout new_branch_name

# modify or create new files in the new_branch_name
# add the files to the staging area
git add new_file/.
// 
git add *.c
#commit to the local database
git commit -m "comment"

# 从暂存区(statge)中移除,git add会将文件移到暂存区(statge)
git reset HEAD <file>
# 撤销文件的修改(该文件未放到暂存区),使用该命令,会将暂存区的文件覆盖工作目录的文件
git checkout -- [file] 

# navigate back to the master branch
git checkout master
# retrieve changes from remote server before  committing own changes
# 'orgin': the project from remote server
git pull origin master

# review and merge, commit own changes to master branch
git merge new_branch_name

# push own changes from master to remote server
git  push

# 本地创建的分支推送到远程仓库上并创建分支: 

本次Git多个账户管理:

https://github.com/git-ecosystem/git-credential-manager/blob/main/docs/multiple-users.md

git staging a file:
# add newfile to staging area
git add newfile
# remove newfile from statging area
# --cached: keep the file when remove from staging area
# -f: force removal
git rm --cached newfile

git commit  is just a snapshot of the entire project at a certain time.Git doesn’t record the individual changes done to the fiels; it takes a picure of the entire project.

parent  : the previous state of the project

Git Ignores

To ignore files, create a file named .gitignore and list the files or folders to ignore in it.

Remember that the .gitignore global file should be placed at the root of your repository.

If you put it in a directory, only the matching files in that directory will be ignored.

.gitignore lineWhat is ignoredExample
config.txtconfig.txt in any dirconfig.txt local\config.txt
build/any build directory and files in it. But not a file named buildbuild/target.bin
buildAny build direcotry,all files in it , and any file named buildbuild/target.bin   output/build
*.exeAny files with the extension .exetarget.exe
bin/*.exeAny files wiht *.exe  in the bin/ directory
temp*All files with name beginning by tempTemp temp.bin
**/configsAny diretory named configs
**/cinfigs/local.pyAny file named local.py in any dir named configs
output/**/result.exeAny file named result.exe in any dire outputoutput/result.exe  result/latest/result.exe

use ! to except file

Remote

linking repositories to remote


# 显示远程仓库地址对应的名称
git remote 
>>>orgin
# git remote add [name] [link] ,其中,name一般为origin
# 给url定义一个名字,方便在本地使用,如origin表示git仓库的地址
git remote add origin https://github.com/mtsitoara/todo-list.git

# 查看远程仓库地址
git remote -v
# [简称] [remote url]
>>> origin  https://github.com/goddenty/notes.git (fetch)
>>> origin  https://github.com/goddenty/notes.git (push)

# 查看remote地址,远程分支,还有本地分支与之相对应关系等信息
git remote show origin

# 远程仓库分支删除后,本地分支查看仍旧存在,需要删除
git remote prune origin


# 从远程仓库中获取更新,但是不会merge到工作目录
git fetch [remote-name]

# 远程仓库Rename和Remove
git remote rename <current-remote-name> <new-remote-name>
git remote rm [remote-name]

# 给远程地址添加别名
git remote add <Name> <Remote Url>


git config --local credential.helper ""

# 当本地有多个Git账户时,针对不同的Repo设置不同的用户名
# 方法1:切换到指定的Repo目录下
git remote set-url https://<accountname>@github.com/goddenty/....git
# 方法2:切换到指定的Repo目录下
# 找到.git/config文件,修改如下节点的值
# [remote "origin"]
# url = https://goddenty@github.com/goddenty/DotNetFeatures.git

Push

# 当远程分支不存在时,则可以将本地分支推送到远程并创建:
# 需要切换到待推送的分支  u:--set-upstream
$ git push -u origin <RemoteBranchName>
$ git push -u origin [username/]<RemoteBranchName>
# or
$ git push -u origin <localBranchName>:<RemoteBranchName>
# 将本地dev分支推送到远程release/cu_v1.0分支
$ git push -u origin dev:release/cu_v1.0

# 将本地的提交强制推送到remote上,覆盖之前的提交。
git push -f 

Pull

pull remote changes to local

用于从远程获取代码并合并到本地的分支

git pull其实就是 git fetch 和 git merge FETCH_HEAD的缩写。

在下面的命令中,如果省略[local_branchName],则会将修改merge到本地当前切换的分支。

git  pull [remote host] [remote_branchName]:[local_branchName]

Tag

# Create Tag
git tag -a v1.4 -m 'my version 1.4'

# 追加tag到之前的某个版本
git tag -a v1.2 9fceb02

# 将tag推送到remote
git push origin [tagname]
# 推送所有tags到remote
git push origin --tags
# 删除tag
git tag -d <tagname>
$ git tag -d v1.4-lw
Deleted tag 'v1.4-lw' (was e7d5add)
# 将删除的tag推送的remote
git push <remote> :refs/tags/<tagname>
$ git push origin :refs/tags/v1.4-lw
To /git@github.com:schacon/simplegit.

Add

# 一次添加多个文件
git add <file1> <file2>
# 使用通配符批量添加文件
git add Source/**

 git add **/Retrieve*.md

Commits

在不同的Commit之间切换:

git log --oneline

# 每次commit都有ID
# 如
commit 75f7b636e2b0eab231768caa86a7e5235d4ed979
Author: goddenty <goddenty@163.com>
Date:   Tue Dec 3 11:10:32 2019 +0800

    update fs

commit 7a862daf5c6a6823ade6be9cfe01164733de25d9

#未checkout前,Head指向Working Directory,即master
# checkout之前,确保Working Diretory 为Clean状态
# 如有未提交的文件,则需要stash

#使用checkout commitname 命令切换到指定的commit版本上
git checkout 75f7b636
# 此时Header指针指向了#75f7b636版本的commit
# 切换到旧版本上后,需要注意:
# 1.最好不要修改历史版本中的文件内容

# 返回到最新的commit
git checkout master

撤销commit:

revert 会产生一个新的Commit,从而实现撤销某个Commit带来的改变

git log --oneline

git revert commitName

Branch:

# 查询所有本地仓库的分支
git branch [--list] [-a]
>>> master
    Branch1

# pattern使用通配符来列出特定的branch。
git branch --list [<pattern>]
    
# 查询所有本地和远程的仓库的分支
# 需要先使用git fetch 获取remote更新
git branch -al
>>> master
    Branch1
    remotes/origin/HEAD
    remotes/origin/master

# 查询所有远程的仓库分支
git branch -r
>>>  origin/HEAD -> origin/master
     origin/NewBrac
     origin/master
     origin/readme-edits

# 显示本地分支及追踪的远程分支
git branch -vv   
    

# 切换到另一个branch, 如果分支不存在,则会报错
git checkout AnotherBranchName

# 创建分支并切换到该分支
$ git checkout -b <newBranchName>

# 切换到远程分支
git checkout -b <localBranchName> origin/<RemoteBranchName>


# 当远程分支存在,本地不存在远程分支时:
$ git fetch origin develop(develop为远程仓库的分支名)

$ git checkout -b dev(本地分支名称) origin/develop(远程分支名称)

# 删除本地分支
$ git branch -d <LocalBranchName>
# 强制删除本地分支 D shorhand for --delete --force
$ git branch -D <LocalBranchName>

# checkout 某个commit
$ git checkout -b <new-branch-name> <commit-id-sha>

eg..

# create local branch to develop feature
$ git checkout -b AddUserBranch
# developing ...
# commit and push
$ git commit -m 'aaa'
# This will create a new remote branch
$ git push -u origin ym/AddUserBranch

# create pull request in azure
# The remote branch AddUserBranch will auto delete

# sync with remote
$ git pull

# delete local branch
$ git branch -d AddUserBranch
# delete the remote tag stored in the local client
$ git remote prune origin


# Or

# we could create branch directly in the remote
$ git pull
# show branches
$ git branch -al
# create and checkout to local branch
git checkout -b <localBranchName> origin/<RemoteBranchName>




注意:切换分支前,应确保当前分支所有修改都commit,或者stashing

如果是基于当前分支创建分支,则不需要所有修改都add,commit或者stash

Switch

# Switch to another branch or create a new branch more safer
git switch [-c // --create] <branchName>

// switch to previous branch.
git switch -
// grow a new branch from specific commit.
git switch -c <branchName> <Commit>

# 当switch的本次分支不存在,且和远程分支名称一样时,会自动创建本地分支,并关联到远程分支。

Checkout

checkout除了可以切换分支外,还可以舍弃工作区的修改


# 基于当前分支创建新的分支
git checkout -b <NewBranchName>

# 基于远程分支创建分支
git fetch
git branch -a
git checkout -b <NewLocalBranchName> <RemoteBranchName>

# 将某次提交(包含之前的体提交)的版本创建到新的分支上(
git checkout <commitId> -b <NewBranchName>

# checkout remote branch
git checkout -b <branch> --track <remote>/<branch>
# 表示用版本库的文件覆盖工作区的文件。
git checkout -- readme.txt
# 从某个提交中取出文件并覆盖工作区的文件。
# filename 支持文件名,目录,通配符,如Util.cs, Helper/, *.cs等
git checkout <commitId> -- <filename>
# 从某个分支中取出文件
git checkout <branchName> -- <filename>

Merge

# 普通的merge会将另外一个分支的提交记录引入到log中
# 如将FeatureA分支merge到main分支中:
git checkout main
git merge FeatureA

# 添加squash参数后,只会将文件的更改merge到目标分支中,提交记录不会merge
# 执行完此命令后,需要使用git commit来提交此次的merge信息,相当于把FeatureA的提交记录给压缩为main分支里的一条记录
# 并且也不会再自动产生Merge的日志。
git merge --squash FeatureA

merge后,log中会出现一条提交记录:

1e32be6 (HEAD -> nameproperty) Merge branch ‘master’ into nameproperty

Conflicts:

发生情况:

在本地main上新建分支test;

在main上修改某个文件,并提交

在test分支上修改同样的文件的同一个地方并提交

执行 git merge main会提示冲突

git status,查看分支状态

打开冲突文件,并修改冲突

git add 冲突文件,将此文件的冲突状态标记为resolved

git commit,将merge的文件commit

Tag

# Query tag
git tag
# create tag
git tag [tagName]
# query remote tag
git tag -r
# delete tag
git tag -d [tagName]

Stash

# 简写
# stash the current working tree
git stash 
# pop a single stash(remove from stash list)
git stash pop 


git stash list [<options>]
# Show the changes recorded in the stash entry as a diff
git stash show [<options>] [<stash>]
git stash drop [-q|--quiet] [<stash>]
# [pop]:remove a single stashed state and apply to the working tree
# [apply]: not remove , and just apply to the working tree
git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
git stash branch <branchname> [<stash>]
git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
	     [-u|--include-untracked] [-a|--all] [-m|--message <message>]
	     [--] [<pathspec>…​]]
git stash clear
git stash create [<message>]
git stash store [-m|--message <message>] [-q|--quiet] <commit>

Restore

git-restore – Restore working tree files(not invoke git add or commit)

撤销未Add或Commit的修改

Reset

删除某个commit,log中将不显示删除的commit,reflog中仍会存在。

# soft 不删除工作空间改动代码,是撤销commit,不撤销 git add
# hard 删除工作空间改动代码,撤销commit,同时撤销git add
# Head^ 是指上一个版本,也可以写成Head~1
# 如果撤销最新的2次commit,则可以使用HEAD~2

# 默认的模式是--mixed
# 将已经提交的修改从commit中删除,不会留在暂存区,会放在工作空间中,需要重新Add和Commit

# 已经提交的修改会从commit中删除,但是会留在暂存区,无需Add,需要重新commit
git reset --soft Head^   

# 已经提交的修改会从commit中删除,并且不会留在暂存区。
# 如果要推送到remote,则需要加-f
git reset --hard Head^   

# 根据commitId撤销commit
# 执行此命令后,将在log中看不到此次之后的提交

git reset --hard <GitCommitId>

# 如果要恢复到最新的提交,则需要使用reflog找到最新提交的CommitHash,再次使用此命令即可。
# 执行后,commit的历史记录恢复,工作空间的代码仍然保持之前的修改,需要git restore 

# 查看所有提交的log
git reflog

Rebase

变更分支的基线:

当依据main分支建立branch后,此时main分支有新的提交,则在创建的branch上使用rebase,则可以将main上的变更merge到该分支上,与merge不一样的是,不会有merge的提交记录。
如:

main分支提交记录:

53dbc1e (HEAD -> master) Add comment property

864be4a Add gender property

5cf36a7 Add name property

f7ca985 Add a new class

branch分支提交记录

f9061a4 (HEAD -> nameproperty) rename name to nameA

5cf36a7 Add name property

f7ca985 Add a new class

rebase以后的分支提交记录(resolve conflict后):

138f39b (HEAD -> nameproperty) rename name to nameA

53dbc1e (master) Add comment property

864be4a Add gender property

5cf36a7 Add name property

f7ca985 Add a new class

git checkout <branchName>
git rebase <anotherBranchName>

Revert

与reset不同的地方:

用新的commit来还原之前的commit,而reset是删除之前的某次的commit

Command:


# 默认revert会还原并提交新的修改,需要添加-n (--no-commit) 来控制不要commit revert的文件。
git revert -n commit-id
# 当前的操作会回到指令执行之前的样子,相当于啥也没有干,回到原始的状态
git revert --abort

check-pick

$ git cherry-pick <HashA> <HashB>

$ git cherry-pick A..B 

Azure devops中可以到pull request中选择cherry-pick来merge到其他分支,如果提示有冲突,无法提交,则需要本地处理

假如有一个hotfix(基于release分支创建)提交到了release分支,同时需要把这个hotfix cherry-pick到main分支,步骤如下:

//切换到relase分支(包含新增加的功能或Fix),并查看log,记录下提交的Id
git log --oneline -n 5


//切换到目标分支main(未包含新功能或Fix)
git checkout main
//基于目标分支main分支创建新分支
git checkout -b <user>/relaseHF/Fix-on-main
//cherry pick from release commit
git cherry-pick <提交的Id>

//resolve conflicts
//推荐使用可视化工具来resolve

//Commit changed file

//PUSH to remote
git push 

// Create a pull request

log


# --oneline is shorthand for --pretty=oneline
git log --oneline [-n 4]  [filename]

不常用命令:

搜索代码文件

git grep <reg> <ref>
# -n 显示行号
# -l 只返回文件名

# Looks for time_t in all tracked .c and .h files in the working directory and its subdirectories.
git grep 'time_t' -- '*.[ch]'

# Looks for solution, excluding files in Documentation.
git grep solution -- :^Documentation


Blame

git blame <filename>
# 显示index.js中400到420行中的信息
git blame -L 400,420 index.js

Show

显示一个或多个对象,如blobs,trees,tags,commits

# 显示提交包含的信息
git show <commitid>
# 显示某一分支的文件内容
git show <branch>:<file>

Tortoise Git

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

豫ICP备2021008859号-1