Stage, commit, push
https://stackoverflow.com/questions/572549/difference-between-git-add-a-and-git-add
1 | |
We can undo git add before commit. The following will remove file.txt from the current index (the “about to be committed” list) without changing anything else
1 | |
To unstage all changes
1 | |
To push a local branch to the remote repo
1 | |
To delete a remote branch
1 | |
To discard or unstage uncommitted local changes, to restore working tree files
1 | |
Index and the working tree
To tell Git not to track changes to your local file/folder (meaning git status won’t detect changes to it)
1 | |
There is no “recursive” option to git update-index, thus if we want to git skip worktree on all tracked files inside a directory and its subdirectories, we should first cd into that directory, then run the following command (without any modification):
1 | |
To tell Git to track changes to your local version once again (so you can commit the changes)
1 | |
Similarly, to the above operation recursively, run the following command:
1 | |
Show information about files in the index and the working tree
1 | |
The options (git ls-files -v .) are:
1 | |
List files ignored with skip-worktree
1 | |
You want to let git ignore deleted files? The code below works on deleted as well as modified files to ignore it when you do a git status.
1 | |
https://stackoverflow.com/a/3453788/7636942
查看某一个commit都改动了哪些文件
1 | |
将某一个文件恢复到某次提交时的版本
1 | |
Check who (which commit, when, author) changed which lines in a file
1 | |
Undo the most recent commit in Git (GitHub)
https://stackoverflow.com/a/927386/7636942
1 | |
#1This command is responsible for the undo. It will undo your last commit while leaving your working tree (the state of your files on disk) untouched. You’ll need to add them again before you can commit them again).#2Make corrections to working tree files, for example, delete the wrongly committed files.#3To remove (not revert) a commit that has been pushed to the server, this command rewrites history on the GitHub server.
Replace git reset HEAD~ by git reset HEAD~3 to undo the 3 most recent commits.
Branching and merging
Warning: when creating a pull request on GitHub, it should alway be preferred to create a new branch dedicated for this, for example a branch called pull_request_branch. In this way, we can always commit to the master/main branch without affecting the created pull request.
Lists existing branches, the current branch will be highlighted in green and marked with an asterisk
1 | |
Creates a new branch and switch to it at the same time
1 | |
This is equivalent to
1 | |
Switches (back) to the master branch (It’s best to have a clean working state when one switches branches)
1 | |
Makes some changes in a new branch, then merges that branch back into the master branch
1 | |
If a branch branch_name_1 is not fully merged, git branch -d branch_name_1 raises an error which prevents this deletion. If we are sure we want to delete it, do the following
1 | |
Shows changes
1 | |
Git fetch remote branch
1 | |
…where <rbranch> is the remote branch or source ref and <lbranch> is the as yet non-existent local branch or destination ref you want to track and which you probably want to name the same as the remote branch or source ref. If we are working with GitHub, <remote> can just be the https address that is usually used to do git clone (without any further modification).
How to create a new remote branch out of an old commit?
1 | |
How to clone a specific branch?
It seems that in some cases, only the specified branch will be cloned even if --single-branch is not used.
1 | |
Find the most recent common ancestor of two branches
1 | |
这个命令会输出一个提交哈希值,这就是两个分支的最近共同祖先。
选择性地将一个commit的内容(哈希值为 [commit_hash])从一个branch复制到另一个branch
1 | |
cherry-pick 到新 branch 上生成的 commit 将会有一个自己独立的哈希值,只带来了原来 [commit_hash] 中的内容。
合并(squash)或编辑当前 branch 最近(N+1)个提交
1 | |
git rebase -i 交互模式里 commit 从上到下列出顺序提交的历史commits。可以通过修改每个 commit 前方的文本来进行操作。
pick保持提交不变squash将该 commit 与前一个 commit 合并 并且合并 commit messagesreword修改 commit message 但保留 commit content
N 可以适当多取一些,因为并不是必须修改其中的每一个 commit。
举例:
HEAD~3: 这里 HEAD 表示当前分支的最新 commit,HEAD~3 表示从当前 commit 回溯3个 commits,包括最新提交和最近的3个 commits(一共4个 commits)。
commitA(HEAD, the latest commit)commitB(HEAD~1)commitC(HEAD~2)commitD(HEAD~3)
git rebase -i HEAD~3 进入一个交互模式 编辑从 commitD 到 commitA 的这些提交。该例子中假如其中一个commit(比如commitC)是一个 merge commit(commit message 为 Merge branch 'A' into B),那么git rebase -i的交互模式将展开 A branch 中的每一个commit,所以看到的 commit 行数有可能大于4。
子模块
git clone 之后,进行子模块的初始化和更新
1 | |
Why submodules in git? It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other.
To add a new submodule you use the git submodule add command with the absolute or relative URL of the project you would like to start tracking. The given URL is recorded into .gitmodules. This file contains one subsection per submodule. This file is version-controlled with your other files, like your .gitignore file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from.
git submodule init 读取 .gitmodules 文件并在 .git/config 中添加子模块的信息。git submodule init creates a record about submodules in the .git/config file, but does not check out the contents of the submodule repositories.
git submodule update 更新和检出每一个子模块的内容:
- 如果需要保持子模块在特定的已知状态,
git submodule update更新 submodules 到主项目中记录的特定 commit。当你运行git submodule update时,Git 会将子模块检出到父项目中记录的那个具体提交哈希,这确保了子模块的状态与父项目中的记录一致。 - 如果需要最新的子模块版本,
git submodule update --remote更新 submodules 到 remote repository 特定分支的最新 commit。
如何确定父项目中记录的子模块的特定 commit 呢?
在 Git 中,子模块的目标 commit 记录其实是保存在父项目的某个特定 commit 里的。这些目标 commit 记录存储在父项目的 Git 对象中,而不是一个单独的配置文件。具体来说,父项目的每个 commit 都包含了子模块的特定 commit 哈希。当你添加一个子模块到父项目时,父项目会记录子模块在某个特定时间点的 commit 哈希。你可以通过查看父项目提交的树对象来找到子模块的 commit 哈希。
如何查看子模块的目标 commit 呢?.gitmodules 文件和 .git/config 文件并不包含子模块的具体提交哈希。可以使用 git ls-tree HEAD 查看子模块的 commit 哈希。
1 | |
git ls-tree HEAD 用于查看指定 commit(在这种情况下是 HEAD)的树对象内容,它类似 ls命令,会列出当前路径下的文件和子文件夹。该命令的输出中,对应submodules的那些行显示的哈希值就是我们要找的子模块的具体 commit 哈希,这个哈希值对应子模块仓库的一个特定 commit。
The word tree is rather overloaded in Git (well, and, in computing in general).
- A tree object, in Git, is an internal data structure that records a directory tree or sub-tree. It contains one entry per file or sub-directory (or, for submodules, a gitlink entry for that submodule).
- The work-tree or working tree (or other variations of this spelling) refers to the place in which you do your work.
Checking states
Displays the state of the working directory and the staging area
1 | |
Shows commit logs
1 | |
Reference logs. git reflog doesn’t traverse HEAD’s ancestry at all. The reflog is an ordered list of the commits that HEAD has pointed to: it’s undo history for your repo. The reflog isn’t part of the repo itself (it’s stored separately to the commits themselves) and isn’t included in pushes, fetches or clones; it’s purely local.
1 | |
Checks the version of Git
1 | |
To view file diff in git before commit, for a file that we haven’t git added yet
1 | |
The above command does not work for files that are already git added. If we want to see already added changes
1 | |
可视化不同分支之间的提交历史
1 | |
--oneline means oneline version.
git stash
git stash is handy if you need to quickly switch context and work on something else, but you’re mid-way through a code change and aren’t quite ready to commit. git stash 命令的作用就是将目前还不想提交的但是已经修改的内容进行保存至堆栈中,后续可以在某个分支上恢复出堆栈中的内容。stash中的内容不仅仅可以恢复到原先开发的分支,也可以恢复到其他任意指定的分支上。
1 | |
The git stash command takes your uncommitted changes (both staged and unstaged), saves them away for later use. The stash is local to your Git repository; stashes are not transferred to the server when you push. By default, running git stash will stash: (1) changes that have been added to your index (staged changes); (2) changes made to files that are currently tracked by Git (unstaged changes). But it will not stash: (1) new files in your working copy that have not yet been staged; (2) files that have been ignored. Adding the -u option (or --include-untracked) tells git stash to also stash your untracked files. You can include changes to ignored files as well by passing the -a option (or --all) when running git stash.
1 | |
You are not limited to a single stash. You can create multiple stashes, and then use git stash list to view them. By default, stashes are identified simply as a “WIP” – work in progress – on top of the branch and commit that you created the stash from. You can annotate your stashes with a description, using git stash save "message".
By default, git stash pop will re-apply the most recently created stash: stash@{0}. You can choose which stash to re-apply by doing e.g. git stash pop stash@{2}
删除在远程仓库中已不存在的分支的引用
git fetch -p(-p 是 --prune 的简写)清理本地引用列表,删除在远程仓库中已不存在的分支的引用。
Before fetching, remove any remote-tracking references that no longer exist on the remote.
Config
1 | |
git ignore
Ignore some files
1 | |
Ignore some files locally
1 | |
Don’t forget Index and the working tree section.
Reset cached credentials on MacOS (password, personal access tokens, etc.)
On MacOS, we can use command line to delete existing credentials and then re-enter our new username and/or password when prompted.
To delete existing credentials, enter the following command:
1 | |
If successful, nothing will print out.
Now when we try to clone a GitHub repository (using https), we will be prompted to enter our credentials.
How to Change Your GitHub Remote Authentication from Username + Password to Personal Access Token
cdto the local directory, rungit remote -vto check the current remote.- Remove the old remote. For example, run
git remote remove originto remove theoriginremote. - Add your new remote in the following format:
git remote add origin https://<TOKEN>@github.com/<USERNAME>/<REPO>.git
That’s all. This can be verified by running git remote -v
How to clone a private GitHub repo
1 | |
where <pat> means Personal Access Token.