Differences between revisions 32 and 37 (spanning 5 versions)
Revision 32 as of 2020-08-20 01:26:02
Size: 6565
Editor: SamatJain
Comment:
Revision 37 as of 2023-03-01 08:30:42
Size: 8092
Editor: SamatJain
Comment: sign previous commits
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:

See also: [[CodingStyle/Git]]
Line 144: Line 146:
=== Interactive rebase ===

Interactive rebase for only certain commits:
{{{#!highlight sh numbers=off
# Rebase only the last 2 commits
git rebase -i HEAD~2
# All commits that are on feature branch, but not on trunk branch
git rebase -i trunk
}}}

=== Retroactively sign all previous commits ===

Uses rebase, so this will invalidate other checkouts.

{{{#!highlight sh numbers=off
git rebase --exec 'git commit --amend --no-edit --no-verify -S' -i --root
git rebase --committer-date-is-author-date -i --root
# check
git log --pretty=fuller
}}}

Source: [[https://peterbabic.dev/blog/git-sign-previous-commits-keeping-dates/|Git sign previous commits keeping dates by Peter Babič]]


== Problems ==

=== Cannot lock ref error ===

{{{
error: cannot lock ref 'refs/remotes/origin/bugfix/SPL-178301-lookups-cache-results-incorrectly':
}}}

is caused by your local repository's copy of the origin repository's branches getting corrupted. To fix:

{{{#!highlight sh numbers=off
git remote prune origin
}}}

It will not touch any of your local branches with your edits, or anything remote, just your local repo's knowledge of remote branches.
Line 248: Line 290:
== git-email-based workflow ==

An e-mail-based workflow is preferred by many projects, including the Linux kernel.

 * [[https://blog.brixit.nl/git-email-flow-versus-github-flow/|Git email flow vs Github flow]]
 * [[https://git-send-email.io/|git-send-email.io]] helps you get up and running w/ git-email

See also: CodingStyle/Git

Workflow for gitorious and github

Initial checkout:

Toggle line numbers
   1 # Fork repo on gitorious/github
   2 # Pull repo from gitorious/github
   3 # Add remote for upstream, e.g.
   4 cd Spoon-Knife
   5 git remote add upstream git://github.com/octocat/Spoon-Knife.git
   6 git fetch upstream

See Configuring a remote for a fork

When needing to merge upstream changes back into master:

Toggle line numbers
   1 # Make sure we're in the branch we want to be in (i.e. master)
   2 git checkout master
   3 git fetch upstream
   4 # Merge from master branch of upstream into current branch
   5 git merge upstream/master

Cookbook

Delete remote branch

Toggle line numbers
git push origin :name-of-remote-branch
# OR
git push origin --delete name-of-remote-branch

Reverting changes

Amend the previous commit that has not been propogated (i.e. undo it, then start a new one with the pending changes in the index):

git commit --amend -a -m "New commit message"

Undo a commit that has not been propagated:

git reset --soft HEAD^

just changes the repository without changing the files you've edited on disk. However:

git reset --hard HEAD^

will reset both repository and revert files.

Once a commit that has been propagated, there is no way to undo. However, the following will create a new commit undoing the previous commit's changes:

git revert HEAD

To only change a commit message for a commit that has not been propogated:

git commit --amend

Pull with rebase instead of merge

git pull --rebase

Configure a branch to always do a rebase instead of a merge:

git config branch.$BRANCH_NAME.rebase true

Enforce .gitignore

Remove files from the repository that should have been ignored by .gitignore:

git rm -r --cached .
git add .
git status
git commit -m ".gitignore is now working"

Toggle line numbers
# Search commit log (i.e. messages) for given needle in all branches
git log --all --grep='needle'
# As above, but search reflog (much slower)
git log -g --grep='needle'
# Search contents of commits
git grep -F 'needle' $(git rev-list --all)
# Search contents of commit in a large repository
git rev-list --all | parallel -j4 -k -X git grep --color=always -F 'needle'
# Search branches (has problems)
git branch -a | tr -d \* | parallel -k git grep --color=always -iF 'needle'

Ignore whitespace bullshit

# Ignore white space when pulling or merging
git pull -Xignore-space-change
git merge -Xignore-space-change
git merge -Xignore-all-space

# Ignore white space changes when diff'ing
git diff --ignore-space-change

Rebase a branch

Toggle line numbers
# Without having branch-you-want-to-rebase checked out
git rebase branch-you-want-to-rebase branch-to-rebase-from
# With having branch-you-want-to-rebase checked out
git checkout branch-you-want-to-rebase
git rebase branch-to-rebase-from

Rebase off a branch that itself had been rebased (keep the un-rebased branch around as old-branch-to-rebase-from):

Toggle line numbers
git rebase --onto branch-to-rebase-from old-branch-to-rebase-from branch-you-want-to-rebase

If you want to rebase but get updated stamps (do this independently of reordering/merging commits with git rebase -i:

Toggle line numbers
git rebase --ignore-date

Interactive rebase

Interactive rebase for only certain commits:

Toggle line numbers
# Rebase only the last 2 commits
git rebase -i HEAD~2
# All commits that are on feature branch, but not on trunk branch
git rebase -i trunk

Retroactively sign all previous commits

Uses rebase, so this will invalidate other checkouts.

Toggle line numbers
git rebase --exec 'git commit --amend --no-edit --no-verify -S' -i --root
git rebase --committer-date-is-author-date -i --root
# check
git log --pretty=fuller

Source: Git sign previous commits keeping dates by Peter Babič

Problems

Cannot lock ref error

error: cannot lock ref 'refs/remotes/origin/bugfix/SPL-178301-lookups-cache-results-incorrectly':

is caused by your local repository's copy of the origin repository's branches getting corrupted. To fix:

Toggle line numbers
git remote prune origin

It will not touch any of your local branches with your edits, or anything remote, just your local repo's knowledge of remote branches.

Per-repository user settings

Toggle line numbers
git config user.name 'Samat K Jain'
git config user.email 'nobody@example.com'

Cleaning

Toggle line numbers
# Discard all unstaged changes in CWD
git checkout -- .
# Remove untracked files and directories, dry run. `-n` for dry run.
git clean -df -n

GPG Signing

Toggle line numbers
   1 # GPG sign all previous commits. Careful!
   2 git filter-branch -f --commit-filter 'git commit-tree -S "$KEY_ID"' HEAD

Submodules

In the below, TARGET_DIR is something like vendor/some-package.

Cloning a project w/ submodules

First clone:

Toggle line numbers
git clone --recurse-submodules …

If you forgot --recurse-submodules, can run:

Toggle line numbers
git submodule update --init --recursive

Adding submodules to a project

Toggle line numbers
git submodule add $REPOSITORY_URL $TARGET_DIRECTORY

You need to start tracking the new .gitmodules file (just like .gitignore), as well as a "file" representing the submodule. git status will show it as $TARGET_DIRECTORY.

Toggle line numbers
git add .gitmodules $TARGET_DIRECTORY
git commit -m 'Started tracking $REPOSITORY_URL as submodule'

Update submodules

Go to each submodule, fetch, and update:

Toggle line numbers
git submodule update --remote --recursive
# git commit

Remove submodules

Go to each submodule, fetch, and update:

Toggle line numbers
git submodule rm $TARGET_DIR
# git commit
# Completely remove submodule (will need to be init again if you go backwards in history) to save disk space
rm -Rf .git/modules/$TARGET_DIR

Will be done with a git pull automatically if submodule.recurse option is True.

Misc

Tell git to track a specific branch of a submodule, e.g. "master":

Toggle line numbers
git config -f .gitmodules submodule.${TARGET_DIR}.branch master
# commit .gitmodules

-f is specified so that .gitmodule can be updated and other people using the repository can track the same branch. Omit this if you don't care.

Settings

Toggle line numbers
# `--recursive` for everything but `git clone`
git config --global submodule.recurse true
# Show summary of submodule changes in `git status`
git config --global status.submodulesummary true
# Prettier diff for submodules
git config --global diff.submodule log

Interesting reading

The Git Parable: Describes building a system like git, from the ground-up

CIA's git tips & tricks sheet is interesting, and oddly similar to this one.

git-email-based workflow

An e-mail-based workflow is preferred by many projects, including the Linux kernel.


CategoryCheatSheet

SamatsWiki: CheatSheet/Git (last edited 2025-02-28 05:15:15 by SamatJain)