Skip to content

Instantly share code, notes, and snippets.

@therealdreg
Last active July 14, 2022 22:13
Show Gist options
  • Save therealdreg/8abe5e229c9f6049770bfaa0131c34e6 to your computer and use it in GitHub Desktop.
Save therealdreg/8abe5e229c9f6049770bfaa0131c34e6 to your computer and use it in GitHub Desktop.
https://blog.verslu.is/git/git-rebase/
https://github.blog/2015-06-08-how-to-undo-almost-anything-with-git/
https://raturi.in/blog/cleaning-git-repository/
https://stackoverflow.com/questions/9813816/git-pull-after-forced-update
https://stackoverflow.com/questions/7175869/managing-hotfixes-when-develop-branch-is-very-different-from-master
https://medium.com/swlh/squash-and-rebase-git-basics-5cb1be1e0dac
https://davitenio.wordpress.com/2008/09/27/git-merge-after-git-cherry-pick-avoiding-duplicate-commits/
GIT FLOW DAY:
### Step 1: Checkout a new working branch from updated master ###
git checkout -b <branchname>
### Step 2: Make Changes ###
git add
git commit -m "description of changes"
### Step 3: Sync with remote ###
git checkout master
git pull --rebase
### Step 4: Update branch ###
git checkout <branchname>
git rebase master
In case of conflicts: resolve conflict by looking at the files in question.
git add <resolved files>
git rebase --continue
### Step 5: Update remote branch ###
check first if history is ok:
git log
git push -f origin <branchname>
### Step 6: Squash your last N commits ###
git rebase --interactive HEAD~N
### Step 7: Push Changes ###
_alternativelly create pull request and merge changes to master via UI_
git checkout master
git merge <branchname>
git push
### Step 7: Delete working branch ###
git branch -d <branchname>
git push origin :<branchname>
---
### Other squash way
WARNING: First make sure you commit your work—check that git status is clean
(since git reset --hard will throw away staged and unstaged changes)
Then:
# check the commit before the first squashed (3)
git log -n 3
# git reset to commit before the first squashed
git reset --hard HEAD~2
# HEAD@{1} is where the branch was just before the previous command.
# This command sets the state of the index to be as it would just
# after a merge from that commit:
git merge --squash HEAD@{1}
# Commit those squashed changes. The commit message will be helpfully
# prepopulated with the commit messages of all the squashed commits:
git commit -m "description of changes"
# check if the log is ok
git log
# update remote branch
git push -f origin <branchname>
---
## Delete all history in main branch and keep the repo in the current state:
git config --get remote.origin.url
git checkout --orphan orphan_name
git add -A
git commit -am "commit message"
git branch -D main
git branch -m main
git push -f origin main
git gc --aggressive --prune=all
# Get the last output git config --get remote.origin.url
git remote set-url origin <URL>
git branch --set-upstream-to=origin/main main
Note: You should delete all other branches and tags, because they may still
contain the old history.
---
How get the latest code from master into my feature branch without having all
those merge commits in the history.
(This is also for valid for Git pull after forced update push -f)
I use this all the time to get the latest code from master into my feature branch without
having all those merge commits in the history.
# Pull with rebase
# A regular pull is fetch + merge, but what you want is fetch + rebase. This is an
option with the pull command:
git pull --rebase
# In your particular case, (push -f) commits have been removed which you don't want to be
reapplied. This has to be done manually. Therefore, the rebase needs to be interactive so
these commits can be skipped:
git pull --rebase=interactive
---
Git pull after forced update (push -f) OPTION2:
# To receive the new commits
git fetch
# You can reset the commit for a local branch using git reset.
# To change the commit of a local branch:
git reset origin/main --hard
# Be careful though, as the documentation puts it:
# Resets the index and working tree. Any changes to tracked files in the
working tree since <commit> are discarded.
---
Git pull after forced update (push -f) OPTION3:
# To receive the new commits
git fetch
# If you want to actually keep whatever changes you've got locally - do a --soft reset instead.
Which will update the commit history for the branch, but not change any files in the working
directory (and you can then commit them).
# You can replay your local commits on top of any other commit/branch using git rebase:
git rebase -i origin/main
# This will invoke rebase in interactive mode where you can choose how to apply each individual commit
that isn't in the history you are rebasing on top of.
# If the commits you removed (with git push -f) have already been pulled into the local history, they
will be listed as commits that will be reapplied - they would need to be deleted as part of the rebase or
they will simply be re-included into the history for the branch - and reappear in the remote history on the next push.
---
Git pull after forced update (push -f) OPTION4:
This won't fix branches that already have the code you don't want in them (see below for how to do that),
but if they had pulled some-branch and now want it to be clean (and not "ahead" of origin/some-branch)
then you simply:
git checkout some-branch # where some-branch can be replaced by any other branch
git branch base-branch -D # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch # recreating branch with correct commits
If you have contaminated branches, you can create new ones based off the new "dumb branch"
and just cherry-pick commits over.
Ex:
git checkout feature-old # some branch with the extra commits
git log # gives commits (write down the id of the ones you want)
git checkout base-branch # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch
Now feature-new is your branch without the extra (possibly bad) commits!
# HOT FIX from devel to master cherry pick
he simplest way to get some commits from one branch to another is cherry-picking.
Assuming that your fix in master has the commit hash HASH and you want to take that hotfix into your devel branch, do a git checkout devel followed by a git cherry-pick HASH. That's it.
If you want to take all changes from master into devel, you can achieve that with
git checkout devel
git rebase master
If you have the opposite scenario (you make a hotfix during development in a devel branch and want to take that fix into master before devel gets fully merged into master), the workflow is quite similar. Assuming that the hotfix has the hash HOTFIX_HASH, do this:
git checkout master
git cherry-pick HOTFIX_HASH
Now, the commit is present in master and devel. To get around this, type
git checkout devel
git rebase master
and the commit will disappear from devel since it's already present in master.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment