Git: Difference between revisions
(→TASKS) |
No edit summary |
||
(35 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=== TASKS === | === TASKS === | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! New shared central bare repo | ||
|- | |- | ||
| On central server (aka | | On central server (aka morosoph): | ||
cd development(...) | cd development(...) | ||
git init --bare --shared mynewthang.git | git init --bare --shared mynewthang.git | ||
On development box | On development box | ||
cd development(...) | cd development(...) | ||
git clone | git clone morosoph:development/mynewthang.git | ||
# this will create a new empty repo with no branch yet | # this will create a new empty repo with no branch yet | ||
# create files, | # TO CREATE MASTER BRANCH (this is the only way): | ||
# create files, git add, git commit, git push | |||
Back on bitpost | Back on bitpost | ||
git clone mynewthang.git # to create a working copy on server, if desired | git clone mynewthang.git # to create a working copy on server, if desired | ||
Line 28: | Line 28: | ||
rm -rf mything-temp | rm -rf mything-temp | ||
cd mything | cd mything | ||
code .gitignore # as needed | |||
git add (whatever you want to track) | git add (whatever you want to track) | ||
git commit -a -m "init repo" && git push | git commit -a -m "init repo" && git push | ||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Fetch a branch from remote without checking it out | |||
|- | |||
| Good for when you are rebasing a feature branch. | |||
git fetch origin develop:develop | |||
You would think <code>git fetch --all</code> would do it but does not (it fetches the active branch from ''all origins'' - seriously wtf, who ever wants THAT??). | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Completely reset an out-of-sync branch to 100% match the remote | |||
|- | |||
| Sometimes some other idiot rebased the remote branch on you. Make sure you are on the right branch, locally. Then to completely force-reset it: | |||
git reset --hard origin/thebranchname | |||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
Line 43: | Line 56: | ||
master | master | ||
* moodboom-quick-http | * moodboom-quick-http | ||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Get a file from another branch | |||
|- | |||
| Grab the latest version in otherBranch and dump it into your current branch main: | |||
git switch main | |||
git restore --source otherBranch -- myfile.js | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Find a file across branches | |||
|- | |||
| It's clunky, two steps, and you have to glob out the whole fucking name: | |||
# get the commits that involved the filename | |||
git log --all -- '**/*namebits*' | |||
# even better, get the filenames too, and see if it was added or removed: | |||
git log --all --stat -- '**/*namebits*' | |||
# now find the branch with one of those commits: | |||
git branch -a --contains #commithash# | |||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
Line 59: | Line 90: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Interactive rebase with squash | ||
|- | |- | ||
| | | Excellent to do when on your own feature branch. Illegal to do if branch is shared AT ALL! | ||
git | git rebase -i myparentbranch | ||
# work through squash and merge - gitlens may help with squash if you use vscode for EDITOR | |||
git push -f | |||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
Line 72: | Line 104: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! git | ! Fetch from one origin (eg gitlab) and push to another | ||
|- | |||
| My GitLab is usually a mirror, and therefore a push target. But if you edit a file in GitLab, you may need to pull it from remote "gitlab" and push it to remote "sc", like this: | |||
git fetch gitlab develop:develop | |||
git push sc | |||
This assumes you have something like the following in your config: | |||
[remote "sc"] | |||
url = git@shitcutter.com:the-digital-age/rad-scripts.git | |||
fetch = +refs/heads/*:refs/remotes/origin/* | |||
[remote "github.com"] | |||
url = git@github.com:moodboom/rad-scripts.git | |||
fetch = +refs/heads/*:refs/remotes/origin/* | |||
[remote "gitlab.com"] | |||
url = git@gitlab.com:moodboom/rad-scripts.git | |||
fetch = +refs/heads/*:refs/remotes/origin/* | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Merging conflicts after diverging | |||
|- | |- | ||
| Revert local changes in a file to HEAD | | Revert local changes in a file to HEAD | ||
Line 80: | Line 129: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Create and push a feature branch | ||
|- | |- | ||
| This will move recent commits AND uncommitted changes into a new branch (but you probably want to finish by cleaning out commits from starting branch, and repulling after you merge the feature). | | This will move recent commits AND uncommitted changes into a new branch (but you probably want to finish by cleaning out commits from starting branch, and repulling after you merge the feature). | ||
Line 91: | Line 140: | ||
# OR, if you don't want the config, you have to be more specific: | # OR, if you don't want the config, you have to be more specific: | ||
# git push -u origin feature/whiz-bang | # git push -u origin feature/whiz-bang | ||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! getting upstream commits into your GitLab GITFLOW fork | |||
|- | |||
| NOTE: This doesn't work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don't have one yet. | |||
This is very easy if you have left the master branch alone for the parent's commits, and keep your add-on commits in a release-x.x branch, as we have for SWS and SWSS. | |||
cdl | |||
# Clone local repo directly from GitLab (already done on cobra) | |||
git clone git@gitlab.com:moodboom/Simple-Web-Server.git SWS-gitlab-moodboom | |||
cd SWS-gitlab-moodboom | |||
# make sure master is checked out | |||
git branch | |||
# add parent as remote | |||
git remote add ole-upstream git@gitlab.com:eidheim/Simple-Web-Server.git | |||
git fetch ole-upstream | |||
git rebase ole-upstream/master | |||
git push -f origin master | |||
You can now delete the fresh clone, it has done its job. Or leave it for ease-of-use for next rebase. | |||
Now update your bare repo on bitpost, to keep things in sync. | |||
git fetch origin master:master -f | |||
Next, go to dev repo, pull master. Check out release, create a new release from that, and rebase master. (or just create a new release branch off master if that's what you want) It is the gitflow way! | |||
Push your new branch to bare, then push bare to GitLab via something like: | |||
git push --set-upstream origin release/abt-0.0.3 | |||
To complete SW(S)S rebase, update mh-install-sws to use the new branch. Then run it on all your dev boxes, whoop. (Then, code up any fixes, sigh... and push em.. .sigh... and get on with it!) | |||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
Line 148: | Line 227: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Create new branch on server, pull to client | ||
|- | |- | ||
| | | | ||
Line 167: | Line 246: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Merge changes in a single file | ||
|- | |- | ||
| Explanation is [https://stackoverflow.com/a/11593308/717274 here]. | | Explanation is [https://stackoverflow.com/a/11593308/717274 here]. | ||
Line 174: | Line 253: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Remove old branches | ||
|- | |- | ||
| Explanation is [https://stackoverflow.com/a/23961231/717274 here]. | | Explanation is [https://stackoverflow.com/a/23961231/717274 here]. | ||
Line 202: | Line 281: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Pull when untracked files are in the way | ||
|- | |- | ||
| This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo: | | This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo: | ||
Line 209: | Line 288: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Create new branch when untracked files are in the way | ||
|- | |- | ||
| | | | ||
Line 227: | Line 306: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Recreate repo | ||
|- | |- | ||
| | | | ||
Line 238: | Line 317: | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Connect to origin after the fact | ||
|- | |- | ||
| | | | ||
Line 252: | Line 331: | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Ignore local and remote changes to a file | ||
|- | |- | ||
| This is helpful for conf files that need local-specific modifications that shouldn't be pushed. You have to toggle it on/off as needed to get updates! See [http://stackoverflow.com/questions/4348590/how-can-i-make-git-ignore-future-revisions-to-a-file/39776107#39776107 my SO answer]. | | This is helpful for conf files that need local-specific modifications that shouldn't be pushed. You have to toggle it on/off as needed to get updates! See [http://stackoverflow.com/questions/4348590/how-can-i-make-git-ignore-future-revisions-to-a-file/39776107#39776107 my SO answer]. | ||
Line 271: | Line 350: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! git | ! Replace name and email of last commit | ||
|- | |||
| Reset the name and email of the last commit, when you realize you forgot to set them first: | |||
git commit --amend --author="First Last <email>" --no-edit | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Simple tagging (when not using git-sync) | |||
|- | |||
| To add and push a tag to HEAD: | |||
git tag -a 1.2.0 -m "1.2.0" | |||
git push origin 1.2.0 | |||
To add and push a tag attached to a commit with current time as timestamp: | |||
git tag -a 1.2.0 1bc92e2f -m "1.2.0" | |||
git push origin 1.2.0 | |||
To tag a commit while ensuring the timestamp matches is slightly more complicated (but not bad). More details [https://stackoverflow.com/a/21759466/717274 here]: | |||
# Set the HEAD to the old commit that we want to tag | |||
git checkout 9fceb02 | |||
# temporarily set the date to the date of the HEAD commit, and add the tag | |||
GIT_COMMITTER_DATE="$(git show --format=%aD | head -1)" \ | |||
git tag -a v1.2 -m"v1.2" | |||
# push to origin | |||
git push origin --tags | |||
# set HEAD back to whatever you want it to be | |||
git checkout master | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Remove a tag | |||
|- | |||
| This has a long clumsy history, but these instructions should be good into the future. | |||
To remove remote tag(s): | |||
git push --delete origin tag YOUR_TAG_NAME TAG_NAME_2 ... | |||
Remove tag(s) locally: | |||
git tag -d YOUR_TAG_NAME TAG_NAME_2 ... | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Changing branches in a project with submodules | |||
|- | |- | ||
| | | | ||
Line 278: | Line 398: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Hard-reset a misbehaving submodule to parent commit version | ||
|- | |- | ||
| | | | ||
Line 287: | Line 407: | ||
=== CONFIGURATION === | === CONFIGURATION === | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! git | ! Set name and email | ||
|- | |||
| Globally on one machine (note the machine name at end of user name): | |||
git config --global user.email m@thedigitalmachine.com; git config user.name "Michael Behrns-Miller [cast]" | |||
Override for a repository: | |||
git config user.email mbm@equityshift.io; git config user.name "MBM [cast]" | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Set default root to main not master | |||
|- | |||
| I love the idea of a kinder root name, suck it up alt-right down-punchers, lol. | |||
Configure it to always happen: | |||
git config --global init.defaultBranch main | |||
Fix it for a newly initialized repository: | |||
git branch -m main | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Visual difftool and mergetool setup | |||
|- | |- | ||
| Meld is purdy, let's kick its tires. Hope it actually works... | | Meld is purdy, let's kick its tires. Hope it actually works... | ||
Line 332: | Line 469: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Convert to a bare repo | ||
|- | |- | ||
| Start with a normal git repo via [git init]; add your files, get it all set up. Then do this: | | Start with a normal git repo via [git init]; add your files, get it all set up. Then do this: | ||
Line 349: | Line 486: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Convert bare to a mirror of remote (github, facebook, etc) | ||
|- | |- | ||
| You need a bare mirror repo if you want to take someone else's repo and create your own bare to work from. | | You need a bare mirror repo if you want to take someone else's repo and create your own bare to work from. | ||
Line 361: | Line 498: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Create merge-to command | ||
|- | |- | ||
| Add this handy alias command to all git repos' .config file... | | Add this handy alias command to all git repos' .config file... | ||
Line 369: | Line 506: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Fix github diverge from local bare repo following README.md edit | ||
|- | |- | ||
| Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling. | | Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling. | ||
Line 386: | Line 523: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Windows configure notepad++ editor | ||
|- | |- | ||
| | | | ||
Line 392: | Line 529: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Fix push behavior - ONLY PUSH CURRENT doh | ||
|- | |- | ||
| | | | ||
Line 398: | Line 535: | ||
|} | |} | ||
{| class="mw-collapsible mw-collapsed wikitable" | {| class="mw-collapsible mw-collapsed wikitable" | ||
! | ! Multiple upstreams | ||
|- | |- | ||
| Use this to cause AUTOMATIC push/pull to a second origin: | | Use this to cause AUTOMATIC push/pull to a second origin: | ||
Line 407: | Line 544: | ||
|} | |} | ||
=== Git branching strategies === | |||
==== Simplified Gitflow ==== | |||
This is awesome, tight, and well-capable of handling any app with a single primary release (like a website). | |||
RELEASE TAG | |||
o----------------------------o-----------------o------------o------> MASTER | |||
\ / \ \----------/ HOTFIX | |||
\ / \ \ | |||
\----------------------/ \--------------------o-----o------> DEVELOP | |||
\ / | |||
\----------------/ FEATURE | |||
Read more [https://medium.com/goodtogoat/simplified-git-flow-5dc37ba76ea8 here] and [https://gist.github.com/vxhviet/9c4a522921ad857406033c4125f343a5 here]. | |||
==== Gitflow ==== | |||
I was a die-hard believer in gitflow for a while. It's very capable. Too capable. You MIGHT need it if you are supporting multiple versions in production... but in all my cases, it is overkill, compared to Simplified Gitflow. The classic diagram, originally from [http://nvie.com/posts/a-successful-git-branching-model/ here]... | |||
[[File:Git for nice release planning.png]] | [[File:Git for nice release planning.png]] | ||
=== LFS === | |||
Just don't use it. It's shite. If you get stuck working with a repo that requires it, and you are using ssh on linux which just won't work with LFS... you will probably end up with a damaged repo. Fix it with this: | |||
git read-tree HEAD && GIT_LFS_SKIP_SMUDGE=1 git checkout -f HEAD | |||
After that, use '''GIT_LFS_SKIP_SMUDGE=1''' during any git command: | |||
GIT_LFS_SKIP_SMUDGE=1 git pull # etc. | |||
=== My git pages (older) === | |||
[[Track your changes to an open-source project with git]] | |||
[[Using git on Windows]] | |||
[[Portable git]] |
Latest revision as of 20:52, 20 May 2025
TASKS
ExpandNew shared central bare repo |
---|
Expandcreate shared central repo for existing code |
---|
ExpandFetch a branch from remote without checking it out |
---|
ExpandCompletely reset an out-of-sync branch to 100% match the remote |
---|
ExpandSet default branch of a bare repo |
---|
ExpandGet a file from another branch |
---|
ExpandFind a file across branches |
---|
Expandgitflow |
---|
ExpandInteractive rebase with squash |
---|
ExpandPush any branch from bare to origin |
---|
ExpandFetch from one origin (eg gitlab) and push to another |
---|
ExpandMerging conflicts after diverging |
---|
ExpandCreate and push a feature branch |
---|
Expandgetting upstream commits into your GitLab GITFLOW fork |
---|
Expandgetting upstream commits into your GitLab fork |
---|
Expandgetting upstream commits into your GitHub fork |
---|
ExpandClone a bare repo (eg github, gitlab, bb) into a bare repo |
---|
ExpandCreate new branch on server, pull to client |
---|
ExpandMerge changes in a single file |
---|
ExpandRemove old branches |
---|
ExpandWork with two local repos |
---|
ExpandPull when untracked files are in the way |
---|
ExpandCreate new branch when untracked files are in the way |
---|
ExpandRecreate repo |
---|
ExpandConnect to origin after the fact |
---|
ExpandIgnore local and remote changes to a file |
---|
ExpandReplace name and email of last commit |
---|
ExpandSimple tagging (when not using git-sync) |
---|
ExpandRemove a tag |
---|
ExpandChanging branches in a project with submodules |
---|
ExpandHard-reset a misbehaving submodule to parent commit version |
---|
CONFIGURATION
ExpandSet name and email |
---|
ExpandSet default root to main not master |
---|
ExpandVisual difftool and mergetool setup |
---|
ExpandConvert to a bare repo |
---|
ExpandConvert bare to a mirror of remote (github, facebook, etc) |
---|
ExpandCreate merge-to command |
---|
ExpandFix github diverge from local bare repo following README.md edit |
---|
ExpandWindows configure notepad++ editor |
---|
ExpandFix push behavior - ONLY PUSH CURRENT doh |
---|
ExpandMultiple upstreams |
---|
Git branching strategies
Simplified Gitflow
This is awesome, tight, and well-capable of handling any app with a single primary release (like a website).
RELEASE TAG o----------------------------o-----------------o------------o------> MASTER \ / \ \----------/ HOTFIX \ / \ \ \----------------------/ \--------------------o-----o------> DEVELOP \ / \----------------/ FEATURE
Gitflow
I was a die-hard believer in gitflow for a while. It's very capable. Too capable. You MIGHT need it if you are supporting multiple versions in production... but in all my cases, it is overkill, compared to Simplified Gitflow. The classic diagram, originally from here...
LFS
Just don't use it. It's shite. If you get stuck working with a repo that requires it, and you are using ssh on linux which just won't work with LFS... you will probably end up with a damaged repo. Fix it with this:
git read-tree HEAD && GIT_LFS_SKIP_SMUDGE=1 git checkout -f HEAD
After that, use GIT_LFS_SKIP_SMUDGE=1 during any git command:
GIT_LFS_SKIP_SMUDGE=1 git pull # etc.