<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://bitpost.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=M</id>
	<title>Bitpost wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://bitpost.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=M"/>
	<link rel="alternate" type="text/html" href="https://bitpost.com/wiki/Special:Contributions/M"/>
	<updated>2026-04-23T06:24:37Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Kodi&amp;diff=7945</id>
		<title>Kodi</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Kodi&amp;diff=7945"/>
		<updated>2026-03-07T00:56:57Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;KODI IS LIFE&lt;br /&gt;
&lt;br /&gt;
=== Addons ===&lt;br /&gt;
&lt;br /&gt;
=== Metadata ===&lt;br /&gt;
&lt;br /&gt;
This helps fix metadata failures and gaps:&lt;br /&gt;
 wget https://mediaelch-downloads.ameyering.de/releases/v2.12.0/MediaElch_linux_2.12.0_2024-10-13_git-8032465.AppImage&lt;br /&gt;
 chmod +x MediaElch_linux_2.12.0_2024-10-13_git-8032465.AppImage&lt;br /&gt;
 ./MediaElch_linux_2.12.0_2024-10-13_git-8032465.AppImage&lt;br /&gt;
&lt;br /&gt;
=== Tricks and Tips ===&lt;br /&gt;
&lt;br /&gt;
==== Ensure no tearing ====&lt;br /&gt;
&lt;br /&gt;
* Get nvidia-settings working right&lt;br /&gt;
** Ensure 4k, 60 fps&lt;br /&gt;
** TO KILL TEARING YOU MUST FORCE FULL COMPOSITION, it should be a setting under Screen &amp;gt; Advanced&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Config files ====&lt;br /&gt;
See the flatpak config files here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data&lt;br /&gt;
&lt;br /&gt;
The log file is here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data/temp/kodi.log&lt;br /&gt;
&lt;br /&gt;
==== Startup ====&lt;br /&gt;
It should start up using this, on case:&lt;br /&gt;
 ~/scripts/ubuntu/case/start_my_apps.sh&lt;br /&gt;
&lt;br /&gt;
That runs&lt;br /&gt;
 /usr/bin/flatpak run tv.kodi.Kodi --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
Not sure that is working yet tbh...&lt;br /&gt;
&lt;br /&gt;
==== Audio ====&lt;br /&gt;
Flatpak kodi and root system audio are currently fubar.  Out-of-the-box will BREAK YOUR EARS, or worse, remain silent.  To fix it, hardcode pulseaudio with this option:&lt;br /&gt;
 --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
==== Media ====&lt;br /&gt;
Fucking flatpak knows nothing of the root filesystem.  Do this to grant it:&lt;br /&gt;
 sudo flatpak override --filesystem=host tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
If you want to fiddle with giving it less access, you can maybe try something like this but you may have to diddle the whole damned library...&lt;br /&gt;
 sudo flatpak override --reset tv.kodi.Kodi&lt;br /&gt;
 sudo flatpak override --filesystem=/spiceflow/media tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
==== case ====&lt;br /&gt;
Kodi has sadly chosen to go flatpak.&lt;br /&gt;
&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 cd development/config/ubuntu/case/etc/apt/sources.list.d/&lt;br /&gt;
 git rm -f team-xbmc-ubuntu-ppa-noble.sources&lt;br /&gt;
 &lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
Migration from apt to flatpak:&lt;br /&gt;
&lt;br /&gt;
Copy config from apt to flatpak:&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 cp -rp ~/.kodi directory to ~/.var/app/tv.kodi.Kodi&lt;br /&gt;
 mv .kodi data&lt;br /&gt;
 # NOT ~/.var/app/tv.kodi.Kodi/data/.kodi&lt;br /&gt;
 # YES ~/.var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 # NOT ~/var/app/tv.kodi.Kodi/data/.kodi/userdata&lt;br /&gt;
&lt;br /&gt;
==== cast ====&lt;br /&gt;
This is not exactly how i did it but it should be close to correct.&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 sudo rm /etc/apt/sources.list.d/team-xbmc-ubuntu-ppa-oracular.sources&lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
 # add this to &lt;br /&gt;
 flatpak run tv.kodi.Kodi --audio-backend=pulseaudio # and quit, this creates config files&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 mv ~/.kodi data&lt;br /&gt;
 cd ~/development/config/common/home/m&lt;br /&gt;
 mkdir -p .var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 git mv .kodi/userdata/* .var/app/tv.kodi.Kodi/data/userdata/ # might have to move conflicting files?&lt;br /&gt;
 setup_stow.sh&lt;br /&gt;
 # set up kodi alias&lt;br /&gt;
 ne ~/.bashrc_env&lt;br /&gt;
   alias kodi=&amp;quot;flatpak run tv.kodi.Kodi --audio-backend=pulseaudio&amp;quot;&lt;br /&gt;
 # reopen terminal&lt;br /&gt;
 sudo flatpak override --filesystem=host tv.kodi.Kodi&lt;br /&gt;
 kodi&lt;br /&gt;
&lt;br /&gt;
=== HISTORY deprecated ===&lt;br /&gt;
&lt;br /&gt;
install&lt;br /&gt;
* First you must remove any old install:&lt;br /&gt;
 sudo apt remove --autoremove kodi&lt;br /&gt;
 sudo apt autoremove&lt;br /&gt;
* Add official kodi ppa: &lt;br /&gt;
 sudo add-apt-repository ppa:team-xbmc/ppa&lt;br /&gt;
* Install:&lt;br /&gt;
 sudo apt install kodi&lt;br /&gt;
&lt;br /&gt;
Upgrade&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt upgrade # as usual, once you have added the ppa (see Install)&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7944</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7944"/>
		<updated>2026-03-06T21:53:26Z</updated>

		<summary type="html">&lt;p&gt;M: /* Agentic brewhaha */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://claude.ai/settings/usage Usage] - [https://platform.claude.com/settings/members Members]&lt;br /&gt;
&lt;br /&gt;
== FULL POWER MODE ==&lt;br /&gt;
You can use the --dangerously-skip-permissions flag when launching Claude Code:&lt;br /&gt;
 bashclaude --dangerously-skip-permissions&lt;br /&gt;
&lt;br /&gt;
This bypasses all permission prompts so Claude Code will automatically execute commands, write files, etc. without asking.&lt;br /&gt;
&lt;br /&gt;
You can also set it in your project&#039;s .claude/settings.json or global settings to configure allowed tools more granularly if you want a middle ground. For example, allowing specific tools like Bash and file editing without prompts while keeping others gated.&lt;br /&gt;
&lt;br /&gt;
NOTE: --enable-auto-mode is coming soon and is supposed to be as good but safer maybe.&lt;br /&gt;
&lt;br /&gt;
== Agenticizing ==&lt;br /&gt;
[[File:ClaudeAgentic.png]]&lt;br /&gt;
&lt;br /&gt;
== Session Context Preservation ==&lt;br /&gt;
Prompt:&lt;br /&gt;
  when using claude code sessions, how do i preserve the context across sessions, even if they run at the same time&lt;br /&gt;
&lt;br /&gt;
When using Claude Code, you can preserve and share context across sessions using a few methods:&lt;br /&gt;
&lt;br /&gt;
=== CLAUDE.md files ===&lt;br /&gt;
The primary way to persist context is through CLAUDE.md files. Claude Code automatically reads these at the start of each session:&lt;br /&gt;
&lt;br /&gt;
* Project-level: Create a CLAUDE.md in your project root for project-specific context, conventions, and instructions&lt;br /&gt;
* User-level: Create ~/.claude/CLAUDE.md for personal preferences that apply across all projects&lt;br /&gt;
&lt;br /&gt;
=== Session memory with --resume and --continue ===&lt;br /&gt;
&lt;br /&gt;
  claude --continue or -c: Resumes your most recent conversation&lt;br /&gt;
  claude --resume: Opens a session picker to choose from past conversations&lt;br /&gt;
  claude --resume &amp;quot;session-id&amp;quot;: Resumes a specific session by ID&lt;br /&gt;
&lt;br /&gt;
=== For parallel sessions sharing context ===&lt;br /&gt;
If you need multiple simultaneous sessions to share state:&lt;br /&gt;
* Use a shared CLAUDE.md file that all sessions read&lt;br /&gt;
* Write intermediate results or shared state to files in your project that other sessions can read&lt;br /&gt;
* Use claude --print mode for non-interactive sessions that can output to files other sessions consume&lt;br /&gt;
&lt;br /&gt;
=== Session checkpoints ===&lt;br /&gt;
 You can create a checkpoint of your current session&#039;s context by asking Claude Code to summarize the current state, and write it to CLAUDE.md or another file.&lt;br /&gt;
&lt;br /&gt;
For the most current and detailed information, check [docs.claude.com the Claude Code documentation], as features may have been added since my knowledge cutoff.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately [https://claude.ai/settings/data-privacy-controls turn this off], or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=File:ClaudeAgentic.png&amp;diff=7943</id>
		<title>File:ClaudeAgentic.png</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=File:ClaudeAgentic.png&amp;diff=7943"/>
		<updated>2026-03-06T21:52:50Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7942</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7942"/>
		<updated>2026-03-06T21:51:35Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://claude.ai/settings/usage Usage] - [https://platform.claude.com/settings/members Members]&lt;br /&gt;
&lt;br /&gt;
== FULL POWER MODE ==&lt;br /&gt;
You can use the --dangerously-skip-permissions flag when launching Claude Code:&lt;br /&gt;
 bashclaude --dangerously-skip-permissions&lt;br /&gt;
&lt;br /&gt;
This bypasses all permission prompts so Claude Code will automatically execute commands, write files, etc. without asking.&lt;br /&gt;
&lt;br /&gt;
You can also set it in your project&#039;s .claude/settings.json or global settings to configure allowed tools more granularly if you want a middle ground. For example, allowing specific tools like Bash and file editing without prompts while keeping others gated.&lt;br /&gt;
&lt;br /&gt;
NOTE: --enable-auto-mode is coming soon and is supposed to be as good but safer maybe.&lt;br /&gt;
&lt;br /&gt;
== Agentic brewhaha ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Session Context Preservation ==&lt;br /&gt;
Prompt:&lt;br /&gt;
  when using claude code sessions, how do i preserve the context across sessions, even if they run at the same time&lt;br /&gt;
&lt;br /&gt;
When using Claude Code, you can preserve and share context across sessions using a few methods:&lt;br /&gt;
&lt;br /&gt;
=== CLAUDE.md files ===&lt;br /&gt;
The primary way to persist context is through CLAUDE.md files. Claude Code automatically reads these at the start of each session:&lt;br /&gt;
&lt;br /&gt;
* Project-level: Create a CLAUDE.md in your project root for project-specific context, conventions, and instructions&lt;br /&gt;
* User-level: Create ~/.claude/CLAUDE.md for personal preferences that apply across all projects&lt;br /&gt;
&lt;br /&gt;
=== Session memory with --resume and --continue ===&lt;br /&gt;
&lt;br /&gt;
  claude --continue or -c: Resumes your most recent conversation&lt;br /&gt;
  claude --resume: Opens a session picker to choose from past conversations&lt;br /&gt;
  claude --resume &amp;quot;session-id&amp;quot;: Resumes a specific session by ID&lt;br /&gt;
&lt;br /&gt;
=== For parallel sessions sharing context ===&lt;br /&gt;
If you need multiple simultaneous sessions to share state:&lt;br /&gt;
* Use a shared CLAUDE.md file that all sessions read&lt;br /&gt;
* Write intermediate results or shared state to files in your project that other sessions can read&lt;br /&gt;
* Use claude --print mode for non-interactive sessions that can output to files other sessions consume&lt;br /&gt;
&lt;br /&gt;
=== Session checkpoints ===&lt;br /&gt;
 You can create a checkpoint of your current session&#039;s context by asking Claude Code to summarize the current state, and write it to CLAUDE.md or another file.&lt;br /&gt;
&lt;br /&gt;
For the most current and detailed information, check [docs.claude.com the Claude Code documentation], as features may have been added since my knowledge cutoff.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately [https://claude.ai/settings/data-privacy-controls turn this off], or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7941</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7941"/>
		<updated>2026-03-02T00:02:57Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://claude.ai/settings/usage Usage] - [https://platform.claude.com/settings/members Members]&lt;br /&gt;
&lt;br /&gt;
== FULL POWER MODE ==&lt;br /&gt;
You can use the --dangerously-skip-permissions flag when launching Claude Code:&lt;br /&gt;
 bashclaude --dangerously-skip-permissions&lt;br /&gt;
&lt;br /&gt;
This bypasses all permission prompts so Claude Code will automatically execute commands, write files, etc. without asking.&lt;br /&gt;
&lt;br /&gt;
You can also set it in your project&#039;s .claude/settings.json or global settings to configure allowed tools more granularly if you want a middle ground. For example, allowing specific tools like Bash and file editing without prompts while keeping others gated.&lt;br /&gt;
&lt;br /&gt;
== Session Context Preservation ==&lt;br /&gt;
Prompt:&lt;br /&gt;
  when using claude code sessions, how do i preserve the context across sessions, even if they run at the same time&lt;br /&gt;
&lt;br /&gt;
When using Claude Code, you can preserve and share context across sessions using a few methods:&lt;br /&gt;
&lt;br /&gt;
=== CLAUDE.md files ===&lt;br /&gt;
The primary way to persist context is through CLAUDE.md files. Claude Code automatically reads these at the start of each session:&lt;br /&gt;
&lt;br /&gt;
* Project-level: Create a CLAUDE.md in your project root for project-specific context, conventions, and instructions&lt;br /&gt;
* User-level: Create ~/.claude/CLAUDE.md for personal preferences that apply across all projects&lt;br /&gt;
&lt;br /&gt;
=== Session memory with --resume and --continue ===&lt;br /&gt;
&lt;br /&gt;
  claude --continue or -c: Resumes your most recent conversation&lt;br /&gt;
  claude --resume: Opens a session picker to choose from past conversations&lt;br /&gt;
  claude --resume &amp;quot;session-id&amp;quot;: Resumes a specific session by ID&lt;br /&gt;
&lt;br /&gt;
=== For parallel sessions sharing context ===&lt;br /&gt;
If you need multiple simultaneous sessions to share state:&lt;br /&gt;
* Use a shared CLAUDE.md file that all sessions read&lt;br /&gt;
* Write intermediate results or shared state to files in your project that other sessions can read&lt;br /&gt;
* Use claude --print mode for non-interactive sessions that can output to files other sessions consume&lt;br /&gt;
&lt;br /&gt;
=== Session checkpoints ===&lt;br /&gt;
 You can create a checkpoint of your current session&#039;s context by asking Claude Code to summarize the current state, and write it to CLAUDE.md or another file.&lt;br /&gt;
&lt;br /&gt;
For the most current and detailed information, check [docs.claude.com the Claude Code documentation], as features may have been added since my knowledge cutoff.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately [https://claude.ai/settings/data-privacy-controls turn this off], or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Software_reference&amp;diff=7940</id>
		<title>Software reference</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Software_reference&amp;diff=7940"/>
		<updated>2026-03-02T00:00:46Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== TASKS ==&lt;br /&gt;
&lt;br /&gt;
[[AI]]&lt;br /&gt;
&lt;br /&gt;
[[Video Editing]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== APPS ==&lt;br /&gt;
&lt;br /&gt;
A/V: [[Kodi]] - [[VLC]] - [[Blender]] - [[Gimp]] - [[Shotwell]] - [[Davinci Resolve]]&lt;br /&gt;
&lt;br /&gt;
Music: [[FL Studio]] - [[Reaper]] - [[Audacity]] - [[Ampache]] - [[Spotify]] - [[Strawberry]]&lt;br /&gt;
&lt;br /&gt;
Games: [[Steam]] - [[Minecraft]] - [[Twitch]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TOOLS ==&lt;br /&gt;
&lt;br /&gt;
[[Mediawiki]] - [[Wordpress]] - [[Timewarrior]] - [[Workflowy]]&lt;br /&gt;
&lt;br /&gt;
[[LibreOffice]] - [[qBitTorrent]] - [[Cura]]&lt;br /&gt;
&lt;br /&gt;
[[Visual Studio Code|vscode]] - [[ne]] - [[Cursor]] - [[Qt Creator]] - [[Emacs]] - [[GitLab]]&lt;br /&gt;
&lt;br /&gt;
[[irc]] - [[slack]]- [[pidgin]] - [[XMPP]] - [[Rocket.Chat]] - [[zoom]]&lt;br /&gt;
&lt;br /&gt;
[[i3]] - [[UnixPorn]] - [[terminal]] - [[kitty]] - [[screen]] - [[albert]]&lt;br /&gt;
&lt;br /&gt;
[[HandBrake]] - [[simplescreenrecorder]] - [[vokoscreenNG]] - [[osi]] - [[maim]] - [[copyq]]&lt;br /&gt;
&lt;br /&gt;
[[mame]] - [[Simon]] - [[Kaldi]] - [http://www.question2answer.org/ Q2A]&lt;br /&gt;
&lt;br /&gt;
[[Brave]] - [[Vivaldi]] - [[Tor]] - [[Chrome]] - [[Firefox]] - [[Okular]]&lt;br /&gt;
&lt;br /&gt;
[[DBeaver]] - [[pgadmin4]] - [[Studio 3T]] - [[Sqlite Explorer]]&lt;br /&gt;
&lt;br /&gt;
[[postgres]] - [[sqlite]] - [[mongodb]] - [[mysql]] - [[mariadb]] - [[SQL Server]]&lt;br /&gt;
&lt;br /&gt;
[[Docker]] - [[ninja]] - [[CMake]] - [[gcc]] - [[git]] - [[eslint]]&lt;br /&gt;
&lt;br /&gt;
[[TrueNAS]] - [[Linux software raid]] - [[Wireshark]] - [[Apache]]&lt;br /&gt;
&lt;br /&gt;
[[ssh]] - [[gpg]] - [[haproxy]] - [[dnsmasq]] - [[geth]]&lt;br /&gt;
&lt;br /&gt;
[[proxmox]] - [[SPICE]] - [[vnc]] - [[Remote Desktop]] - [[Remmina]]&lt;br /&gt;
&lt;br /&gt;
[[WireGuard]] - [[TailScale]] - [[OpenVPN]]&lt;br /&gt;
&lt;br /&gt;
[[GCP]] - [[AWS]]&lt;br /&gt;
&lt;br /&gt;
[[systemd]] - [[xrandr]] - [[samba]] - [[fail2ban]] - [[ntp]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Software Under Review]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Software Archive]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! OS installation&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 25.10 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 25.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 24.10 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 24.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 22.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Linux barebones quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ventoy|Ventoy ISO boot disk]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Raspberry Pi]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Kali quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Centos quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Cygwin quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[OS X]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Update gentoo kernel]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Upgrade gentoo]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows 10 quickstart&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* [[Cygwin quickstart|Install cygwin]]&lt;br /&gt;
* Disable automatic restarts&lt;br /&gt;
Install Group Policy Editor from an admin Powershell console:&lt;br /&gt;
 @echo off &lt;br /&gt;
 pushd &amp;quot;%~dp0&amp;quot; &lt;br /&gt;
 &lt;br /&gt;
 dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum &amp;gt;List.txt &lt;br /&gt;
 dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum &amp;gt;&amp;gt;List.txt &lt;br /&gt;
 &lt;br /&gt;
 for /f %%i in (&#039;findstr /i . List.txt 2^&amp;gt;nul&#039;) do dism /online /norestart /add-package:&amp;quot;%SystemRoot%\servicing\Packages\%%i&amp;quot; &lt;br /&gt;
 pause&lt;br /&gt;
Run Group Policy Editor to disable restarts:&lt;br /&gt;
 Computer Configuration &amp;gt; Administrative Templates &amp;gt; Windows Components &amp;gt; Windows Update &amp;gt; Configure Automatic Updates&lt;br /&gt;
 (o) Enabled&lt;br /&gt;
 [2] Notify for download and auto install?  Or [3] Auto download and notify for install?  Going with [3], we&#039;ll see.&lt;br /&gt;
 (or...) (o) Enabled: No auto-restart with logged on users for scheduled automatic updates installations&lt;br /&gt;
 ---&lt;br /&gt;
 No auto-restart with logged on users for scheduled automatic updates installation (just in case)&lt;br /&gt;
 (o) Enabled&lt;br /&gt;
 ---&lt;br /&gt;
 (reboot if you had to change it?  or will that wipe it out?  tbd...) &lt;br /&gt;
In a corporate environment, you should quit your job - I mean, you will likely have to redo this after ANY f&#039;in reboot.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Memtest boot disk&lt;br /&gt;
|-&lt;br /&gt;
| It should be on red-on-black flash drive.  Or, [https://www.memtest86.com/download.htm get a fresh download] of USB zip, it includes a Windows exe to create the boot.  Or use the ISO.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu upgrade / reinstall notes]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and boot from Ubuntu USB&lt;br /&gt;
|-&lt;br /&gt;
| There should always be a boot USB for this in my set, but it needs recreation on new Ubuntu versions...&lt;br /&gt;
# Download the latest 64-bit Ubuntu desktop iso&lt;br /&gt;
# Format a USB drive as FAT (NOT exFAT or NTFS)&lt;br /&gt;
# Burn the iso to the USB, providing a GB of space (we want to add the nvidia driver once booted)&lt;br /&gt;
 sudo usb-creator-gtk&lt;br /&gt;
# Boot with it&lt;br /&gt;
# On startup, select the USB EFI boot option in refind, select &amp;quot;Try Ubuntu&amp;quot;, (on MBPro, hit e and add [ nouveau.noaccel=1] to grub line), hit F10 to start&lt;br /&gt;
# Once it is running, start System Settings, select Software, enable proprietary drivers&lt;br /&gt;
# Install, checking the [download as you go] and [install 3rd party stuff] boxes.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ubuntu set up networking&lt;br /&gt;
|-&lt;br /&gt;
| Install NetworkManager, as the wpagui UI sucks&lt;br /&gt;
* sudo apt-get install network-manager-gnome&lt;br /&gt;
* YOU MUST remove interfaces from /etc/network/interfaces so wpa gives them up to nm-applet&lt;br /&gt;
* add nm-applet to startup if needed - i don&#039;t think it is needed as it seems to start up automatically now - try rebooting first&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Software_reference&amp;diff=7939</id>
		<title>Software reference</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Software_reference&amp;diff=7939"/>
		<updated>2026-03-02T00:00:34Z</updated>

		<summary type="html">&lt;p&gt;M: /* TOOLS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== TASKS ==&lt;br /&gt;
&lt;br /&gt;
[[Video Editing]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== APPS ==&lt;br /&gt;
&lt;br /&gt;
A/V: [[Kodi]] - [[VLC]] - [[Blender]] - [[Gimp]] - [[Shotwell]] - [[Davinci Resolve]]&lt;br /&gt;
&lt;br /&gt;
Music: [[FL Studio]] - [[Reaper]] - [[Audacity]] - [[Ampache]] - [[Spotify]] - [[Strawberry]]&lt;br /&gt;
&lt;br /&gt;
Games: [[Steam]] - [[Minecraft]] - [[Twitch]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TOOLS ==&lt;br /&gt;
&lt;br /&gt;
[[Mediawiki]] - [[Wordpress]] - [[Timewarrior]] - [[Workflowy]]&lt;br /&gt;
&lt;br /&gt;
[[LibreOffice]] - [[qBitTorrent]] - [[Cura]]&lt;br /&gt;
&lt;br /&gt;
[[Visual Studio Code|vscode]] - [[ne]] - [[Cursor]] - [[Qt Creator]] - [[Emacs]] - [[GitLab]]&lt;br /&gt;
&lt;br /&gt;
[[irc]] - [[slack]]- [[pidgin]] - [[XMPP]] - [[Rocket.Chat]] - [[zoom]]&lt;br /&gt;
&lt;br /&gt;
[[i3]] - [[UnixPorn]] - [[terminal]] - [[kitty]] - [[screen]] - [[albert]]&lt;br /&gt;
&lt;br /&gt;
[[HandBrake]] - [[simplescreenrecorder]] - [[vokoscreenNG]] - [[osi]] - [[maim]] - [[copyq]]&lt;br /&gt;
&lt;br /&gt;
[[mame]] - [[Simon]] - [[Kaldi]] - [http://www.question2answer.org/ Q2A]&lt;br /&gt;
&lt;br /&gt;
[[Brave]] - [[Vivaldi]] - [[Tor]] - [[Chrome]] - [[Firefox]] - [[Okular]]&lt;br /&gt;
&lt;br /&gt;
[[DBeaver]] - [[pgadmin4]] - [[Studio 3T]] - [[Sqlite Explorer]]&lt;br /&gt;
&lt;br /&gt;
[[postgres]] - [[sqlite]] - [[mongodb]] - [[mysql]] - [[mariadb]] - [[SQL Server]]&lt;br /&gt;
&lt;br /&gt;
[[Docker]] - [[ninja]] - [[CMake]] - [[gcc]] - [[git]] - [[eslint]]&lt;br /&gt;
&lt;br /&gt;
[[TrueNAS]] - [[Linux software raid]] - [[Wireshark]] - [[Apache]]&lt;br /&gt;
&lt;br /&gt;
[[ssh]] - [[gpg]] - [[haproxy]] - [[dnsmasq]] - [[geth]]&lt;br /&gt;
&lt;br /&gt;
[[proxmox]] - [[SPICE]] - [[vnc]] - [[Remote Desktop]] - [[Remmina]]&lt;br /&gt;
&lt;br /&gt;
[[WireGuard]] - [[TailScale]] - [[OpenVPN]]&lt;br /&gt;
&lt;br /&gt;
[[GCP]] - [[AWS]]&lt;br /&gt;
&lt;br /&gt;
[[systemd]] - [[xrandr]] - [[samba]] - [[fail2ban]] - [[ntp]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Software Under Review]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Software Archive]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! OS installation&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 25.10 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 25.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 24.10 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 24.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 22.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Linux barebones quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ventoy|Ventoy ISO boot disk]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Raspberry Pi]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Kali quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Centos quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Cygwin quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[OS X]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Update gentoo kernel]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Upgrade gentoo]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows 10 quickstart&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* [[Cygwin quickstart|Install cygwin]]&lt;br /&gt;
* Disable automatic restarts&lt;br /&gt;
Install Group Policy Editor from an admin Powershell console:&lt;br /&gt;
 @echo off &lt;br /&gt;
 pushd &amp;quot;%~dp0&amp;quot; &lt;br /&gt;
 &lt;br /&gt;
 dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum &amp;gt;List.txt &lt;br /&gt;
 dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum &amp;gt;&amp;gt;List.txt &lt;br /&gt;
 &lt;br /&gt;
 for /f %%i in (&#039;findstr /i . List.txt 2^&amp;gt;nul&#039;) do dism /online /norestart /add-package:&amp;quot;%SystemRoot%\servicing\Packages\%%i&amp;quot; &lt;br /&gt;
 pause&lt;br /&gt;
Run Group Policy Editor to disable restarts:&lt;br /&gt;
 Computer Configuration &amp;gt; Administrative Templates &amp;gt; Windows Components &amp;gt; Windows Update &amp;gt; Configure Automatic Updates&lt;br /&gt;
 (o) Enabled&lt;br /&gt;
 [2] Notify for download and auto install?  Or [3] Auto download and notify for install?  Going with [3], we&#039;ll see.&lt;br /&gt;
 (or...) (o) Enabled: No auto-restart with logged on users for scheduled automatic updates installations&lt;br /&gt;
 ---&lt;br /&gt;
 No auto-restart with logged on users for scheduled automatic updates installation (just in case)&lt;br /&gt;
 (o) Enabled&lt;br /&gt;
 ---&lt;br /&gt;
 (reboot if you had to change it?  or will that wipe it out?  tbd...) &lt;br /&gt;
In a corporate environment, you should quit your job - I mean, you will likely have to redo this after ANY f&#039;in reboot.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Memtest boot disk&lt;br /&gt;
|-&lt;br /&gt;
| It should be on red-on-black flash drive.  Or, [https://www.memtest86.com/download.htm get a fresh download] of USB zip, it includes a Windows exe to create the boot.  Or use the ISO.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu upgrade / reinstall notes]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and boot from Ubuntu USB&lt;br /&gt;
|-&lt;br /&gt;
| There should always be a boot USB for this in my set, but it needs recreation on new Ubuntu versions...&lt;br /&gt;
# Download the latest 64-bit Ubuntu desktop iso&lt;br /&gt;
# Format a USB drive as FAT (NOT exFAT or NTFS)&lt;br /&gt;
# Burn the iso to the USB, providing a GB of space (we want to add the nvidia driver once booted)&lt;br /&gt;
 sudo usb-creator-gtk&lt;br /&gt;
# Boot with it&lt;br /&gt;
# On startup, select the USB EFI boot option in refind, select &amp;quot;Try Ubuntu&amp;quot;, (on MBPro, hit e and add [ nouveau.noaccel=1] to grub line), hit F10 to start&lt;br /&gt;
# Once it is running, start System Settings, select Software, enable proprietary drivers&lt;br /&gt;
# Install, checking the [download as you go] and [install 3rd party stuff] boxes.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ubuntu set up networking&lt;br /&gt;
|-&lt;br /&gt;
| Install NetworkManager, as the wpagui UI sucks&lt;br /&gt;
* sudo apt-get install network-manager-gnome&lt;br /&gt;
* YOU MUST remove interfaces from /etc/network/interfaces so wpa gives them up to nm-applet&lt;br /&gt;
* add nm-applet to startup if needed - i don&#039;t think it is needed as it seems to start up automatically now - try rebooting first&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Kodi&amp;diff=7938</id>
		<title>Kodi</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Kodi&amp;diff=7938"/>
		<updated>2026-02-26T20:28:19Z</updated>

		<summary type="html">&lt;p&gt;M: /* cast */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;KODI IS LIFE&lt;br /&gt;
&lt;br /&gt;
=== Addons ===&lt;br /&gt;
&lt;br /&gt;
=== Tricks and Tips ===&lt;br /&gt;
&lt;br /&gt;
==== Ensure no tearing ====&lt;br /&gt;
&lt;br /&gt;
* Get nvidia-settings working right&lt;br /&gt;
** Ensure 4k, 60 fps&lt;br /&gt;
** TO KILL TEARING YOU MUST FORCE FULL COMPOSITION, it should be a setting under Screen &amp;gt; Advanced&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Config files ====&lt;br /&gt;
See the flatpak config files here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data&lt;br /&gt;
&lt;br /&gt;
The log file is here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data/temp/kodi.log&lt;br /&gt;
&lt;br /&gt;
==== Startup ====&lt;br /&gt;
It should start up using this, on case:&lt;br /&gt;
 ~/scripts/ubuntu/case/start_my_apps.sh&lt;br /&gt;
&lt;br /&gt;
That runs&lt;br /&gt;
 /usr/bin/flatpak run tv.kodi.Kodi --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
Not sure that is working yet tbh...&lt;br /&gt;
&lt;br /&gt;
==== Audio ====&lt;br /&gt;
Flatpak kodi and root system audio are currently fubar.  Out-of-the-box will BREAK YOUR EARS, or worse, remain silent.  To fix it, hardcode pulseaudio with this option:&lt;br /&gt;
 --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
==== Media ====&lt;br /&gt;
Fucking flatpak knows nothing of the root filesystem.  Do this to grant it:&lt;br /&gt;
 sudo flatpak override --filesystem=host tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
If you want to fiddle with giving it less access, you can maybe try something like this but you may have to diddle the whole damned library...&lt;br /&gt;
 sudo flatpak override --reset tv.kodi.Kodi&lt;br /&gt;
 sudo flatpak override --filesystem=/spiceflow/media tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
==== case ====&lt;br /&gt;
Kodi has sadly chosen to go flatpak.&lt;br /&gt;
&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 cd development/config/ubuntu/case/etc/apt/sources.list.d/&lt;br /&gt;
 git rm -f team-xbmc-ubuntu-ppa-noble.sources&lt;br /&gt;
 &lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
Migration from apt to flatpak:&lt;br /&gt;
&lt;br /&gt;
Copy config from apt to flatpak:&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 cp -rp ~/.kodi directory to ~/.var/app/tv.kodi.Kodi&lt;br /&gt;
 mv .kodi data&lt;br /&gt;
 # NOT ~/.var/app/tv.kodi.Kodi/data/.kodi&lt;br /&gt;
 # YES ~/.var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 # NOT ~/var/app/tv.kodi.Kodi/data/.kodi/userdata&lt;br /&gt;
&lt;br /&gt;
==== cast ====&lt;br /&gt;
This is not exactly how i did it but it should be close to correct.&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 sudo rm /etc/apt/sources.list.d/team-xbmc-ubuntu-ppa-oracular.sources&lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
 # add this to &lt;br /&gt;
 flatpak run tv.kodi.Kodi --audio-backend=pulseaudio # and quit, this creates config files&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 mv ~/.kodi data&lt;br /&gt;
 cd ~/development/config/common/home/m&lt;br /&gt;
 mkdir -p .var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 git mv .kodi/userdata/* .var/app/tv.kodi.Kodi/data/userdata/ # might have to move conflicting files?&lt;br /&gt;
 setup_stow.sh&lt;br /&gt;
 # set up kodi alias&lt;br /&gt;
 ne ~/.bashrc_env&lt;br /&gt;
   alias kodi=&amp;quot;flatpak run tv.kodi.Kodi --audio-backend=pulseaudio&amp;quot;&lt;br /&gt;
 # reopen terminal&lt;br /&gt;
 sudo flatpak override --filesystem=host tv.kodi.Kodi&lt;br /&gt;
 kodi&lt;br /&gt;
&lt;br /&gt;
=== HISTORY deprecated ===&lt;br /&gt;
&lt;br /&gt;
install&lt;br /&gt;
* First you must remove any old install:&lt;br /&gt;
 sudo apt remove --autoremove kodi&lt;br /&gt;
 sudo apt autoremove&lt;br /&gt;
* Add official kodi ppa: &lt;br /&gt;
 sudo add-apt-repository ppa:team-xbmc/ppa&lt;br /&gt;
* Install:&lt;br /&gt;
 sudo apt install kodi&lt;br /&gt;
&lt;br /&gt;
Upgrade&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt upgrade # as usual, once you have added the ppa (see Install)&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Kodi&amp;diff=7937</id>
		<title>Kodi</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Kodi&amp;diff=7937"/>
		<updated>2026-02-26T20:25:42Z</updated>

		<summary type="html">&lt;p&gt;M: /* cast */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;KODI IS LIFE&lt;br /&gt;
&lt;br /&gt;
=== Addons ===&lt;br /&gt;
&lt;br /&gt;
=== Tricks and Tips ===&lt;br /&gt;
&lt;br /&gt;
==== Ensure no tearing ====&lt;br /&gt;
&lt;br /&gt;
* Get nvidia-settings working right&lt;br /&gt;
** Ensure 4k, 60 fps&lt;br /&gt;
** TO KILL TEARING YOU MUST FORCE FULL COMPOSITION, it should be a setting under Screen &amp;gt; Advanced&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Config files ====&lt;br /&gt;
See the flatpak config files here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data&lt;br /&gt;
&lt;br /&gt;
The log file is here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data/temp/kodi.log&lt;br /&gt;
&lt;br /&gt;
==== Startup ====&lt;br /&gt;
It should start up using this, on case:&lt;br /&gt;
 ~/scripts/ubuntu/case/start_my_apps.sh&lt;br /&gt;
&lt;br /&gt;
That runs&lt;br /&gt;
 /usr/bin/flatpak run tv.kodi.Kodi --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
Not sure that is working yet tbh...&lt;br /&gt;
&lt;br /&gt;
==== Audio ====&lt;br /&gt;
Flatpak kodi and root system audio are currently fubar.  Out-of-the-box will BREAK YOUR EARS, or worse, remain silent.  To fix it, hardcode pulseaudio with this option:&lt;br /&gt;
 --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
==== Media ====&lt;br /&gt;
Fucking flatpak knows nothing of the root filesystem.  Do this to grant it:&lt;br /&gt;
 sudo flatpak override --filesystem=host tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
If you want to fiddle with giving it less access, you can maybe try something like this but you may have to diddle the whole damned library...&lt;br /&gt;
 sudo flatpak override --reset tv.kodi.Kodi&lt;br /&gt;
 sudo flatpak override --filesystem=/spiceflow/media tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
==== case ====&lt;br /&gt;
Kodi has sadly chosen to go flatpak.&lt;br /&gt;
&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 cd development/config/ubuntu/case/etc/apt/sources.list.d/&lt;br /&gt;
 git rm -f team-xbmc-ubuntu-ppa-noble.sources&lt;br /&gt;
 &lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
Migration from apt to flatpak:&lt;br /&gt;
&lt;br /&gt;
Copy config from apt to flatpak:&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 cp -rp ~/.kodi directory to ~/.var/app/tv.kodi.Kodi&lt;br /&gt;
 mv .kodi data&lt;br /&gt;
 # NOT ~/.var/app/tv.kodi.Kodi/data/.kodi&lt;br /&gt;
 # YES ~/.var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 # NOT ~/var/app/tv.kodi.Kodi/data/.kodi/userdata&lt;br /&gt;
&lt;br /&gt;
==== cast ====&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 sudo rm /etc/apt/sources.list.d/team-xbmc-ubuntu-ppa-oracular.sources&lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
 # add this to &lt;br /&gt;
 flatpak run tv.kodi.Kodi --audio-backend=pulseaudio # and quit, this creates config files&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 mv ~/.kodi data&lt;br /&gt;
 cd ~/development/config/common/home/m&lt;br /&gt;
 mkdir -p .var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 git mv .kodi/userdata/* .var/app/tv.kodi.Kodi/data/userdata/ # might have to move conflicting files?&lt;br /&gt;
 setup_stow.sh&lt;br /&gt;
 # set up kodi alias to: flatpak run tv.kodi.Kodi --audio-backend=pulseaudio&lt;br /&gt;
 # that&#039;s not how i did it but it should be close to correct&lt;br /&gt;
&lt;br /&gt;
=== HISTORY deprecated ===&lt;br /&gt;
&lt;br /&gt;
install&lt;br /&gt;
* First you must remove any old install:&lt;br /&gt;
 sudo apt remove --autoremove kodi&lt;br /&gt;
 sudo apt autoremove&lt;br /&gt;
* Add official kodi ppa: &lt;br /&gt;
 sudo add-apt-repository ppa:team-xbmc/ppa&lt;br /&gt;
* Install:&lt;br /&gt;
 sudo apt install kodi&lt;br /&gt;
&lt;br /&gt;
Upgrade&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt upgrade # as usual, once you have added the ppa (see Install)&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Kodi&amp;diff=7936</id>
		<title>Kodi</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Kodi&amp;diff=7936"/>
		<updated>2026-02-26T20:15:52Z</updated>

		<summary type="html">&lt;p&gt;M: /* Install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;KODI IS LIFE&lt;br /&gt;
&lt;br /&gt;
=== Addons ===&lt;br /&gt;
&lt;br /&gt;
=== Tricks and Tips ===&lt;br /&gt;
&lt;br /&gt;
==== Ensure no tearing ====&lt;br /&gt;
&lt;br /&gt;
* Get nvidia-settings working right&lt;br /&gt;
** Ensure 4k, 60 fps&lt;br /&gt;
** TO KILL TEARING YOU MUST FORCE FULL COMPOSITION, it should be a setting under Screen &amp;gt; Advanced&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Config files ====&lt;br /&gt;
See the flatpak config files here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data&lt;br /&gt;
&lt;br /&gt;
The log file is here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data/temp/kodi.log&lt;br /&gt;
&lt;br /&gt;
==== Startup ====&lt;br /&gt;
It should start up using this, on case:&lt;br /&gt;
 ~/scripts/ubuntu/case/start_my_apps.sh&lt;br /&gt;
&lt;br /&gt;
That runs&lt;br /&gt;
 /usr/bin/flatpak run tv.kodi.Kodi --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
Not sure that is working yet tbh...&lt;br /&gt;
&lt;br /&gt;
==== Audio ====&lt;br /&gt;
Flatpak kodi and root system audio are currently fubar.  Out-of-the-box will BREAK YOUR EARS, or worse, remain silent.  To fix it, hardcode pulseaudio with this option:&lt;br /&gt;
 --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
==== Media ====&lt;br /&gt;
Fucking flatpak knows nothing of the root filesystem.  Do this to grant it:&lt;br /&gt;
 sudo flatpak override --filesystem=host tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
If you want to fiddle with giving it less access, you can maybe try something like this but you may have to diddle the whole damned library...&lt;br /&gt;
 sudo flatpak override --reset tv.kodi.Kodi&lt;br /&gt;
 sudo flatpak override --filesystem=/spiceflow/media tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
==== case ====&lt;br /&gt;
Kodi has sadly chosen to go flatpak.&lt;br /&gt;
&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 cd development/config/ubuntu/case/etc/apt/sources.list.d/&lt;br /&gt;
 git rm -f team-xbmc-ubuntu-ppa-noble.sources&lt;br /&gt;
 &lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
Migration from apt to flatpak:&lt;br /&gt;
&lt;br /&gt;
Copy config from apt to flatpak:&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 cp -rp ~/.kodi directory to ~/.var/app/tv.kodi.Kodi&lt;br /&gt;
 mv .kodi data&lt;br /&gt;
 # NOT ~/.var/app/tv.kodi.Kodi/data/.kodi&lt;br /&gt;
 # YES ~/.var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 # NOT ~/var/app/tv.kodi.Kodi/data/.kodi/userdata&lt;br /&gt;
&lt;br /&gt;
==== cast ====&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 sudo rm /etc/apt/sources.list.d/team-xbmc-ubuntu-ppa-oracular.sources&lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
 # add this to &lt;br /&gt;
 kodi # and quit, this creates config files&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 mv ~/.kodi data&lt;br /&gt;
 cd ~/development/config/common/home/m&lt;br /&gt;
 mkdir -p .var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 git mv .kodi/userdata/* .var/app/tv.kodi.Kodi/data/userdata/ # might have to move conflicting files?&lt;br /&gt;
 setup_stow.sh&lt;br /&gt;
 # that&#039;s not how i did it but it should be close to correct&lt;br /&gt;
&lt;br /&gt;
=== HISTORY deprecated ===&lt;br /&gt;
&lt;br /&gt;
install&lt;br /&gt;
* First you must remove any old install:&lt;br /&gt;
 sudo apt remove --autoremove kodi&lt;br /&gt;
 sudo apt autoremove&lt;br /&gt;
* Add official kodi ppa: &lt;br /&gt;
 sudo add-apt-repository ppa:team-xbmc/ppa&lt;br /&gt;
* Install:&lt;br /&gt;
 sudo apt install kodi&lt;br /&gt;
&lt;br /&gt;
Upgrade&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt upgrade # as usual, once you have added the ppa (see Install)&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7935</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7935"/>
		<updated>2026-02-04T13:57:03Z</updated>

		<summary type="html">&lt;p&gt;M: /* Session Context Preservation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://claude.ai/settings/usage Usage] - [https://platform.claude.com/settings/members Members]&lt;br /&gt;
&lt;br /&gt;
== Session Context Preservation ==&lt;br /&gt;
Prompt:&lt;br /&gt;
  when using claude code sessions, how do i preserve the context across sessions, even if they run at the same time&lt;br /&gt;
&lt;br /&gt;
When using Claude Code, you can preserve and share context across sessions using a few methods:&lt;br /&gt;
&lt;br /&gt;
=== CLAUDE.md files ===&lt;br /&gt;
The primary way to persist context is through CLAUDE.md files. Claude Code automatically reads these at the start of each session:&lt;br /&gt;
&lt;br /&gt;
* Project-level: Create a CLAUDE.md in your project root for project-specific context, conventions, and instructions&lt;br /&gt;
* User-level: Create ~/.claude/CLAUDE.md for personal preferences that apply across all projects&lt;br /&gt;
&lt;br /&gt;
=== Session memory with --resume and --continue ===&lt;br /&gt;
&lt;br /&gt;
  claude --continue or -c: Resumes your most recent conversation&lt;br /&gt;
  claude --resume: Opens a session picker to choose from past conversations&lt;br /&gt;
  claude --resume &amp;quot;session-id&amp;quot;: Resumes a specific session by ID&lt;br /&gt;
&lt;br /&gt;
=== For parallel sessions sharing context ===&lt;br /&gt;
If you need multiple simultaneous sessions to share state:&lt;br /&gt;
* Use a shared CLAUDE.md file that all sessions read&lt;br /&gt;
* Write intermediate results or shared state to files in your project that other sessions can read&lt;br /&gt;
* Use claude --print mode for non-interactive sessions that can output to files other sessions consume&lt;br /&gt;
&lt;br /&gt;
=== Session checkpoints ===&lt;br /&gt;
 You can create a checkpoint of your current session&#039;s context by asking Claude Code to summarize the current state, and write it to CLAUDE.md or another file.&lt;br /&gt;
&lt;br /&gt;
For the most current and detailed information, check [docs.claude.com the Claude Code documentation], as features may have been added since my knowledge cutoff.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately [https://claude.ai/settings/data-privacy-controls turn this off], or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7934</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7934"/>
		<updated>2026-02-04T13:56:29Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://claude.ai/settings/usage Usage] - [https://platform.claude.com/settings/members Members]&lt;br /&gt;
&lt;br /&gt;
== Session Context Preservation ==&lt;br /&gt;
Prompt:&lt;br /&gt;
  when using claude code sessions, how do i preserve the context across sessions, even if they run at the same time&lt;br /&gt;
&lt;br /&gt;
When using Claude Code, you can preserve and share context across sessions using a few methods:&lt;br /&gt;
&lt;br /&gt;
# CLAUDE.md files&lt;br /&gt;
The primary way to persist context is through CLAUDE.md files. Claude Code automatically reads these at the start of each session:&lt;br /&gt;
&lt;br /&gt;
* Project-level: Create a CLAUDE.md in your project root for project-specific context, conventions, and instructions&lt;br /&gt;
* User-level: Create ~/.claude/CLAUDE.md for personal preferences that apply across all projects&lt;br /&gt;
&lt;br /&gt;
# Session memory with --resume and --continue&lt;br /&gt;
&lt;br /&gt;
  claude --continue or -c: Resumes your most recent conversation&lt;br /&gt;
  claude --resume: Opens a session picker to choose from past conversations&lt;br /&gt;
  claude --resume &amp;quot;session-id&amp;quot;: Resumes a specific session by ID&lt;br /&gt;
&lt;br /&gt;
# For parallel sessions sharing context&lt;br /&gt;
If you need multiple simultaneous sessions to share state:&lt;br /&gt;
* Use a shared CLAUDE.md file that all sessions read&lt;br /&gt;
* Write intermediate results or shared state to files in your project that other sessions can read&lt;br /&gt;
* Use claude --print mode for non-interactive sessions that can output to files other sessions consume&lt;br /&gt;
&lt;br /&gt;
# Session checkpoints&lt;br /&gt;
 You can create a checkpoint of your current session&#039;s context by asking Claude Code to summarize the current state, and write it to CLAUDE.md or another file.&lt;br /&gt;
&lt;br /&gt;
For the most current and detailed information, check [docs.claude.com the Claude Code documentation], as features may have been added since my knowledge cutoff.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately [https://claude.ai/settings/data-privacy-controls turn this off], or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7933</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7933"/>
		<updated>2026-02-03T02:18:11Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://claude.ai/settings/usage Usage] - [https://platform.claude.com/settings/members Members]&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately [https://claude.ai/settings/data-privacy-controls turn this off], or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7932</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7932"/>
		<updated>2026-02-03T02:16:56Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately [https://claude.ai/settings/data-privacy-controls turn this off], or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;br /&gt;
&lt;br /&gt;
=== [https://platform.claude.com/settings/members Members] ===&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Ubuntu_24.10_upgrade&amp;diff=7931</id>
		<title>Ubuntu 24.10 upgrade</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Ubuntu_24.10_upgrade&amp;diff=7931"/>
		<updated>2026-01-30T13:36:40Z</updated>

		<summary type="html">&lt;p&gt;M: /* TODO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* The usual:&lt;br /&gt;
 mh-update-ubuntu&lt;br /&gt;
 # (ensure all repos are working)&lt;br /&gt;
 # reboot&lt;br /&gt;
 # you can connect via direct proxmox shell (not ssh) but seems robust either way&lt;br /&gt;
 sudo do-release-upgrade&lt;br /&gt;
&lt;br /&gt;
* fix up apt repos&lt;br /&gt;
* fix up stow (esp. systemd stuff)&lt;br /&gt;
* set up purdy rotating kitty term themes&lt;br /&gt;
* reinstall slop if screenshots stopped working&lt;br /&gt;
* reinstall pulseaudio to get media keys working again (why was it removed?)&lt;br /&gt;
 sudo apt install pulseaudio-utils&lt;br /&gt;
* fix brightness control on cobra&lt;br /&gt;
 sudo add-apt-repository ppa:apandada1/brightness-controller&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install brightness-controller&lt;br /&gt;
 brightness-controller&amp;amp;&lt;br /&gt;
&lt;br /&gt;
Check the [[Ubuntu 24.04 upgrade]] for more detailed notes.&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
&lt;br /&gt;
=== cast ===&lt;br /&gt;
* fix gdm3 - if we don&#039;t set /etc/gdm3/custom.conf to AutomaticLogin, gdm3 hangs the entire machine - try it again after a few upgrades&lt;br /&gt;
&lt;br /&gt;
=== bitpost ===&lt;br /&gt;
* cmake and cmake-data are custom installed&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Git&amp;diff=7930</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Git&amp;diff=7930"/>
		<updated>2026-01-10T00:14:50Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== TASKS ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set up a new shitcutter project&lt;br /&gt;
|-&lt;br /&gt;
| Setting up a new project:&lt;br /&gt;
* Create the gitlab project with repo support.&lt;br /&gt;
* Grab the Clone with SSH line&lt;br /&gt;
* Go to morosoph parent folder and paste the git line, adding --bare and --shared, and capitalizing as desired, eg:&lt;br /&gt;
 git clone --shared --bare git@shitcutter.com:the-digital-age/teamtunes/teamtunes-website.git TeamTunes-website.git&lt;br /&gt;
* Configure the bare repo to push to upstream on receive, just copy a hook, eg:&lt;br /&gt;
  🤔 m@morosoph  [~/development/thedigitalage/TeamTunes/TeamTunes-android.git] cp ../TeamTunes-iOS.git/hooks/post-receive hooks/&lt;br /&gt;
Ensure that the hook remote name (typically sc) matches config remote name (typically origin).&lt;br /&gt;
* Go to client and clone:&lt;br /&gt;
 TeamTunes] git clone morosoph:development/thedigitalage/TeamTunes/TeamTunes-website.git&lt;br /&gt;
* Add code and push!&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! New shared central bare repo&lt;br /&gt;
|-&lt;br /&gt;
| On central server (aka morosoph):&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git init --bare --shared mynewthang.git&lt;br /&gt;
On development box&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git clone morosoph:development/mynewthang.git&lt;br /&gt;
 # this will create a new empty repo with no branch yet&lt;br /&gt;
 # TO CREATE MASTER BRANCH (this is the only way):&lt;br /&gt;
 # create files, git add, git commit, git push&lt;br /&gt;
Back on bitpost&lt;br /&gt;
 git clone mynewthang.git # to create a working copy on server, if desired&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! create shared central repo for existing code&lt;br /&gt;
|-&lt;br /&gt;
| Create a bare repo with .git suffix&lt;br /&gt;
 git init --bare --shared mything.git&lt;br /&gt;
Go to existing code and clone the repo next to it, with a temp name.  &lt;br /&gt;
Move .git into the existing code.&lt;br /&gt;
Add code, add a .gitignore as needed, and you&#039;re all set.&lt;br /&gt;
 cd mything/..&lt;br /&gt;
 git clone (bare-repo-host-and-path)mything.git mything-temp&lt;br /&gt;
 mv mything-temp/.git mything/&lt;br /&gt;
 rm -rf mything-temp&lt;br /&gt;
 cd mything&lt;br /&gt;
 code .gitignore # as needed&lt;br /&gt;
 git add (whatever you want to track)&lt;br /&gt;
 git commit -a -m &amp;quot;init repo&amp;quot; &amp;amp;&amp;amp; git push&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fetch a branch from remote without checking it out&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are rebasing a feature branch.&lt;br /&gt;
 git fetch origin develop:develop&lt;br /&gt;
You would think &amp;lt;code&amp;gt;git fetch --all&amp;lt;/code&amp;gt; would do it but does not (it fetches the active branch from &#039;&#039;all origins&#039;&#039; - seriously wtf, who ever wants THAT??).&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Completely reset an out-of-sync branch to 100% match the remote&lt;br /&gt;
|-&lt;br /&gt;
| 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:&lt;br /&gt;
 git reset --hard origin/thebranchname&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default branch of a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| If you want the default branch of a bare repo to be something other than master:&lt;br /&gt;
 git branch&lt;br /&gt;
  * master&lt;br /&gt;
    moodboom-quick-http&lt;br /&gt;
 git symbolic-ref HEAD refs/heads/moodboom-quick-http&lt;br /&gt;
 git branch&lt;br /&gt;
    master&lt;br /&gt;
  * moodboom-quick-http&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Get a file from another branch&lt;br /&gt;
|-&lt;br /&gt;
| Grab the latest version in otherBranch and dump it into your current branch main:&lt;br /&gt;
 git switch main&lt;br /&gt;
 git restore --source otherBranch -- myfile.js&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Find a file across branches&lt;br /&gt;
|-&lt;br /&gt;
| It&#039;s clunky, two steps, and you have to glob out the whole fucking name:&lt;br /&gt;
 # get the commits that involved the filename&lt;br /&gt;
 git log --all -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # even better, get the filenames too, and see if it was added or removed:&lt;br /&gt;
 git log --all --stat -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # now find the branch with one of those commits:&lt;br /&gt;
 git branch -a --contains #commithash#&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gitflow&lt;br /&gt;
|-&lt;br /&gt;
| Gitflow is awesome, using it myself and everywhere I work these days (2020).&lt;br /&gt;
* Devs work out of develop branch&lt;br /&gt;
* Devs create feature branches off develop for any decent-sized work&lt;br /&gt;
* Once develop is stable and you are ready for a release:&lt;br /&gt;
 git tag -a -m &amp;quot;#MAJOR#.#MINOR#&amp;quot;.0 #MAJOR#.#MINOR#.0&lt;br /&gt;
 git checkout -b release/release_#MAJOR#.#MINOR#&lt;br /&gt;
 git push --set-upstream origin release_#MAJOR#.#MINOR#&lt;br /&gt;
 git checkout master &amp;amp;&amp;amp; git merge release/release_#MAJOR#.#MINOR# &amp;amp;&amp;amp; git push&lt;br /&gt;
 git checkout develop # and get back to it!&lt;br /&gt;
* Do hotfixes as needed in release branch, tagged #MAJOR#.#MINOR#.++, merged back into master and develop&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Interactive rebase with squash&lt;br /&gt;
|-&lt;br /&gt;
| Excellent to do when on your own feature branch.  Illegal to do if branch is shared AT ALL!&lt;br /&gt;
 git rebase -i myparentbranch&lt;br /&gt;
 # work through squash and merge - gitlens may help with squash if you use vscode for EDITOR&lt;br /&gt;
 git push -f&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Push any branch from bare to origin&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are force-pushing a branch rebase.&lt;br /&gt;
 git push [-f] origin mybranch:mybranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstream config example&lt;br /&gt;
|-&lt;br /&gt;
| If you edit a file in GitLab, you may need to pull it from remote &amp;quot;gitlab&amp;quot; and push it to remote &amp;quot;sc&amp;quot;, like this:&lt;br /&gt;
 git fetch gitlab develop:develop&lt;br /&gt;
 git push sc&lt;br /&gt;
This assumes you have something like the following in your config:&lt;br /&gt;
 [remote &amp;quot;sc&amp;quot;]&lt;br /&gt;
        url = git@shitcutter.com:the-digital-age/rad-scripts.git&lt;br /&gt;
        fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;github.com&amp;quot;]&lt;br /&gt;
	url = git@github.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;gitlab.com&amp;quot;]&lt;br /&gt;
	url = git@gitlab.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merging conflicts after diverging&lt;br /&gt;
|-&lt;br /&gt;
| Revert local changes in a file to HEAD&lt;br /&gt;
 git checkout -- path/to/file.txt&lt;br /&gt;
Discard ALL LOCAL COMMITS and get the (possibly diverged) remote instead&lt;br /&gt;
 git reset --hard origin/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and push a feature branch&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
 git checkout -b feature/whiz-bang&lt;br /&gt;
 &lt;br /&gt;
 # Do this ONCE: git config --global push.default current&lt;br /&gt;
 # From then on:&lt;br /&gt;
 git push -u&lt;br /&gt;
 &lt;br /&gt;
 # OR, if you don&#039;t want the config, you have to be more specific:&lt;br /&gt;
 # git push -u origin feature/whiz-bang&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab GITFLOW fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
&lt;br /&gt;
This is very easy if you have left the master branch alone for the parent&#039;s commits, and keep your add-on commits in a release-x.x branch, as we have for SWS and SWSS.&lt;br /&gt;
&lt;br /&gt;
 cdl&lt;br /&gt;
 # Clone local repo directly from GitLab (already done on cobra)&lt;br /&gt;
 git clone git@gitlab.com:moodboom/Simple-Web-Server.git SWS-gitlab-moodboom&lt;br /&gt;
 cd SWS-gitlab-moodboom&lt;br /&gt;
 # make sure master is checked out&lt;br /&gt;
 git branch&lt;br /&gt;
 # add parent as remote&lt;br /&gt;
 git remote add ole-upstream git@gitlab.com:eidheim/Simple-Web-Server.git&lt;br /&gt;
 git fetch ole-upstream&lt;br /&gt;
 git rebase ole-upstream/master&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
You can now delete the fresh clone, it has done its job.  Or leave it for ease-of-use for next rebase.&lt;br /&gt;
&lt;br /&gt;
Now update your bare repo on bitpost, to keep things in sync.&lt;br /&gt;
 git fetch origin master:master -f&lt;br /&gt;
&lt;br /&gt;
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&#039;s what you want)  It is the gitflow way!&lt;br /&gt;
&lt;br /&gt;
Push your new branch to bare, then push bare to GitLab via something like:&lt;br /&gt;
 git push --set-upstream origin release/abt-0.0.3&lt;br /&gt;
&lt;br /&gt;
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!)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://gitlab.com/someauthor/theprojectiforked&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
If you haven&#039;t done so, in GitLab, go to [https://gitlab.com/moodboom/Simple-WebSocket-Server/-/settings/repository#js-protected-branches-settings the &amp;quot;Protected Branch&amp;quot; settings] and remove protection from master - it&#039;s just a fact that you&#039;re going to need to force-push to master.&lt;br /&gt;
&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitLab. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
You will want to force-fetch to update the bare repo you may have on bitpost, DO THIS NOW or you will screw things up badly later:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git fetch origin master:master -f&lt;br /&gt;
You should also force-update ALL your dev repos, NOW, for the same reason:&lt;br /&gt;
 git reset --hard HEAD^^^^^^ &amp;amp;&amp;amp; git pull&lt;br /&gt;
NOTE that you may need to remove a remote-tracking branch if you don&#039;t need it any more.  It&#039;s stupidly painful to get right, eg:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git branch -rd eidheim/Simple-WebSocket-Server/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitHub fork&lt;br /&gt;
|-&lt;br /&gt;
| From [http://stackoverflow.com/a/7244456/717274 so...]&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://github.com/someauthor/theprojectiforked.git&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitHub. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
Now master has the latest commits from the fork origin.  You can rebase onto it, if you&#039;ve been working in a branch (good):&lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git rebase master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Clone a bare repo (eg github, gitlab, bb) into a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Say you want a bare repo to be shared by all your dev environments, but you need to push/pull THAT from a central bare repo, too.&lt;br /&gt;
 git clone --bare --shared git@bitbucket.org:equityshift/es-demo.git&lt;br /&gt;
 cd es-demo.git&lt;br /&gt;
 git config remote.origin.fetch &amp;quot;+*:*&amp;quot;&lt;br /&gt;
 git fetch --all&lt;br /&gt;
I was surprised that this was difficult at all, and may still have some lessons to learn...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch on server, pull to client&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 # ON CENTRAL SERVER&lt;br /&gt;
 git checkout master # as needed; we are assuming that master is clean enough as a starting point&lt;br /&gt;
 git checkout -b mynewbranchy&lt;br /&gt;
 &lt;br /&gt;
 # HOWEVER, use this instead if you need a new &amp;quot;clean&amp;quot; repo and even master is dirty...&lt;br /&gt;
 # You need the rm because git &amp;quot;leaves your working folder intact&amp;quot;.&lt;br /&gt;
 git checkout --orphan mynewbranchy&lt;br /&gt;
 git rm -rf .&lt;br /&gt;
 &lt;br /&gt;
 # ON CLIENT&lt;br /&gt;
 git pull&lt;br /&gt;
 git checkout -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
 # if files are in the way from the previously checked-out branch, you can force it...&lt;br /&gt;
 git checkout -f -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merge changes in a single file&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/11593308/717274 here].  &lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git checkout --patch develop my/single/file.cpp&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove old branches&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/23961231/717274 here].  &lt;br /&gt;
Remote:&lt;br /&gt;
 git push origin --delete &amp;lt;branch&amp;gt;&lt;br /&gt;
Local:&lt;br /&gt;
 git branch -d &amp;lt;branch&amp;gt;&lt;br /&gt;
 git fetch &amp;lt;remote&amp;gt; --prune # Delete multiple obsolete tracking branches&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Work with two local repos&lt;br /&gt;
|-&lt;br /&gt;
| Set up a remote, then fetch it as master.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout --track otherplace/master # or other branch as needed; this creates the branch and sets remote in one step, cool&lt;br /&gt;
Set up a remote, then fetch it into a non-master branch, and push it to the active origin.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout otherplace/master # creates it detached, good because we need to name the new branch something other than master&lt;br /&gt;
 git checkout -b new_otherplace_branchname # creates new local branch with a good name&lt;br /&gt;
 git push --set-upstream origin new_otherplace_branchname # takes the branch from the OLD origin and pushes it to the ACTIVE origin, cool!&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Pull when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
| This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo:&lt;br /&gt;
 git fetch --all&lt;br /&gt;
 git reset --hard origin/mymatchingbranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
   git checkout -b bj143 origin/bj143&lt;br /&gt;
      git : error: The following untracked working tree files would be overwritten by checkout:&lt;br /&gt;
      (etc)&lt;br /&gt;
   &lt;br /&gt;
   TOTAL PURGE FIX (too much):&lt;br /&gt;
      git clean  -d  -fn &amp;quot;&amp;quot;&lt;br /&gt;
         -d dirs too&lt;br /&gt;
         -f force, required&lt;br /&gt;
         -x include ignored files (don&#039;t use this)&lt;br /&gt;
         -n dry run&lt;br /&gt;
   &lt;br /&gt;
   BEST FIX (just overwrite what is in the way):&lt;br /&gt;
      git checkout -f -b bj143 origin/bj143&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Recreate repo&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git clone ssh://m@thedigitalmachine.com/home/m/development/thedigitalage/ampache-with-hangthedj-module&lt;br /&gt;
 cd ampache-with-hangthedj-module&lt;br /&gt;
 git checkout -b daily_grind origin/daily_grind&lt;br /&gt;
If you already have the daily_grind branches and just need to connect them:&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Connect to origin after the fact&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git remote add origin ssh:// m@bitpost.com/home/m/development/logs&lt;br /&gt;
 git fetch&lt;br /&gt;
     From ssh:// bitpost/home/m/development/logs&lt;br /&gt;
      * [new branch]      daily_grind -&amp;gt; origin/daily_grind&lt;br /&gt;
      * [new branch]      master     -&amp;gt; origin/master&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git branch -u origin/master master&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ignore local and remote changes to a file &lt;br /&gt;
|-&lt;br /&gt;
| This is helpful for conf files that need local-specific modifications that shouldn&#039;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].&lt;br /&gt;
&lt;br /&gt;
        PREVENT COMMIT OF CHANGES TO A LOCAL FILE&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
        git update-index --skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        RESET TO GET CHANGES AGAIN&lt;br /&gt;
        --------------------------&lt;br /&gt;
        git update-index --no-skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        LIST SKIPPED FILES&lt;br /&gt;
        ------------------&lt;br /&gt;
        git ls-files -v . | grep ^S&lt;br /&gt;
        S app/views/_partials/jsIncludes.scala.html&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Replace name and email of last commit&lt;br /&gt;
|-&lt;br /&gt;
| Reset the name and email of the last commit, when you realize you forgot to set them first:&lt;br /&gt;
 git commit --amend --author=&amp;quot;First Last &amp;lt;email&amp;gt;&amp;quot; --no-edit&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Simple tagging (when not using git-sync)&lt;br /&gt;
|-&lt;br /&gt;
| To add and push a tag to HEAD:&lt;br /&gt;
 git tag -a 1.2.0 -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
To add and push a tag attached to a commit with current time as timestamp:&lt;br /&gt;
 git tag -a 1.2.0 1bc92e2f -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
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]:&lt;br /&gt;
 # Set the HEAD to the old commit that we want to tag&lt;br /&gt;
 git checkout 9fceb02&lt;br /&gt;
 &lt;br /&gt;
 # temporarily set the date to the date of the HEAD commit, and add the tag&lt;br /&gt;
 GIT_COMMITTER_DATE=&amp;quot;$(git show --format=%aD | head -1)&amp;quot; \&lt;br /&gt;
 git tag -a v1.2 -m&amp;quot;v1.2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # push to origin&lt;br /&gt;
 git push origin --tags&lt;br /&gt;
 &lt;br /&gt;
 # set HEAD back to whatever you want it to be&lt;br /&gt;
 git checkout master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove a tag&lt;br /&gt;
|-&lt;br /&gt;
| This has a long clumsy history, but these instructions should be good into the future.&lt;br /&gt;
&lt;br /&gt;
To remove remote tag(s):&lt;br /&gt;
 git push --delete origin tag YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
Remove tag(s) locally:&lt;br /&gt;
  git tag -d YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Changing branches in a project with submodules&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 # always reset the @*$ submodules to proper commits&lt;br /&gt;
 git checkout develop &amp;amp;&amp;amp; git submodule update&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Hard-reset a misbehaving submodule to parent commit version&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git submodule deinit -f .&lt;br /&gt;
 git submodule update --init&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CONFIGURATION ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set name and email&lt;br /&gt;
|-&lt;br /&gt;
| Globally on one machine (note the machine name at end of user name):&lt;br /&gt;
 git config --global user.email m@thedigitalmachine.com;  git config user.name &amp;quot;Michael Behrns-Miller [cast]&amp;quot;&lt;br /&gt;
Override for a repository:&lt;br /&gt;
 git config user.email mbm@equityshift.io;  git config user.name &amp;quot;MBM [cast]&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default root to main not master&lt;br /&gt;
|-&lt;br /&gt;
| I love the idea of a kinder root name, suck it up alt-right down-punchers, lol.&lt;br /&gt;
Configure it to always happen:&lt;br /&gt;
 git config --global init.defaultBranch main&lt;br /&gt;
Fix it for a newly initialized repository:&lt;br /&gt;
 git branch -m main&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - ONLY PUSH CURRENT doh&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.default current&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - always create remote of a local branch name on push&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.autoSetupRemote true&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - allow push -f&lt;br /&gt;
|-&lt;br /&gt;
| When did it become necessary to configure the upstream to allow this?&lt;br /&gt;
 git config receive.denyNonFastForwards false # to allow git push -f&lt;br /&gt;
 git config receive.denyNonFastForwards true # to turn that back off, good practice i guess&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Visual difftool and mergetool setup&lt;br /&gt;
|-&lt;br /&gt;
| Meld is purdy, let&#039;s kick its tires.  Hope it actually works...&lt;br /&gt;
 git config --global diff.tool meld&lt;br /&gt;
 git config --global merge.tool meld&lt;br /&gt;
 git config --global --add difftool.prompt false&lt;br /&gt;
I used to set up kdiff3 manually, like this... (gross)&lt;br /&gt;
* LINUX - put this in ~/.gitconfig&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 &lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* WINDOZE&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* LINUX Before - What a ridiculous pita... copy this into .git/config...&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert to a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Start with a normal git repo via [git init]; add your files, get it all set up.  Then do this:&lt;br /&gt;
 cd repo&lt;br /&gt;
Now you can copy-paste this...&lt;br /&gt;
 mv .git .. &amp;amp;&amp;amp; rm -fr *&lt;br /&gt;
 mv ../.git .&lt;br /&gt;
 mv .git/* .&lt;br /&gt;
 rmdir .git&lt;br /&gt;
 git config --bool core.bare true&lt;br /&gt;
 cd ..&lt;br /&gt;
Don&#039;t copy/paste these, you need to change repo name...&lt;br /&gt;
 mv repo repo.git # rename it for clarity&lt;br /&gt;
 git clone repo.git # (optional, if you want a live repo on the server where you have the bare repo)&lt;br /&gt;
Then you can clean up old branches like daily and daily_grind, as needed.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert bare to a mirror of remote (github, facebook, etc)&lt;br /&gt;
|-&lt;br /&gt;
| You need a bare mirror repo if you want to take someone else&#039;s repo and create your own bare to work from.&lt;br /&gt;
If you did NOT specify --mirror when you first created the bare repo, you can convert to a mirror by adding these last two lines to config, underneath url:&lt;br /&gt;
 [remote &amp;quot;origin&amp;quot;]&lt;br /&gt;
    url = git@github.com:facebook/proxygen.git&lt;br /&gt;
    fetch = +refs/*:refs/*&lt;br /&gt;
    mirror = true&lt;br /&gt;
Now you can fetch from the bare repo:&lt;br /&gt;
 git fetch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create merge-to command&lt;br /&gt;
|-&lt;br /&gt;
| Add this handy alias command to all git repos&#039; .config file...&lt;br /&gt;
 [alias]&lt;br /&gt;
     merge-to = &amp;quot;!gitmergeto() { export tmp_branch=`git branch | grep &#039;* &#039; | tr -d &#039;* &#039;` &amp;amp;&amp;amp; git checkout $1 &amp;amp;&amp;amp; git merge $tmp_branch &amp;amp;&amp;amp; git checkout $tmp_branch; unset tmp_branch; }; gitmergeto&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix github diverge from local bare repo following README.md edit&lt;br /&gt;
|-&lt;br /&gt;
| Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling.&lt;br /&gt;
Fixing it is a PAIN in the ASS, you have to create a new local repo and pull github into that, pull in from your other local repo, push to github, pull to your bare... &lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git quick-http-with-readme-conflict&lt;br /&gt;
 git remote add local ../quick-http&lt;br /&gt;
 git fetch local&lt;br /&gt;
 git merge local/master # merge in changes, likely trivial&lt;br /&gt;
 git push # pushes back to github&lt;br /&gt;
 cd ..&lt;br /&gt;
 mv quick-http.git quick-http.git__gone-out-of-sync-fu-github-readme-editor&lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git --bare&lt;br /&gt;
 cp quick-http.git__gone-out-of-sync-fu-github-readme-editor/config quick-http.git/&lt;br /&gt;
And that MIGHT get you on your way... but I would no longer trust ANY of your local repos...&lt;br /&gt;
This is a serious pita.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows configure notepad++ editor&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 git config --global core.editor &amp;quot;&#039;C:/Program Files (x86)/Notepad++/notepad++.exe&#039; -multiInst -notabbar -nosession -noPlugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstreams&lt;br /&gt;
|-&lt;br /&gt;
| Use this to cause AUTOMATIC push/pull to a second origin:&lt;br /&gt;
 git remote set-url origin --push --add user1@repo1&lt;br /&gt;
 git remote set-url origin --push --add user2@repo2&lt;br /&gt;
 git remote -v show&lt;br /&gt;
Leave out --push if you want to pull as well... but I&#039;d be careful, it&#039;s better if code is changed in one client with this config, and then pushed to the multiple origins from there.  Otherwise, things are GOING TO GET SYNCY-STINKY.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Git branching strategies ===&lt;br /&gt;
==== Simplified Gitflow ====&lt;br /&gt;
This is awesome, tight, and well-capable of handling any app with a single primary release (like a website).&lt;br /&gt;
                         RELEASE TAG&lt;br /&gt;
 o----------------------------o-----------------o------------o------&amp;gt; MASTER&lt;br /&gt;
  \                          /  \                \----------/ HOTFIX&lt;br /&gt;
   \                        /    \                          \&lt;br /&gt;
    \----------------------/      \--------------------o-----o------&amp;gt; DEVELOP&lt;br /&gt;
                                   \                  /&lt;br /&gt;
                                    \----------------/ FEATURE&lt;br /&gt;
&lt;br /&gt;
Read more [https://medium.com/goodtogoat/simplified-git-flow-5dc37ba76ea8 here] and [https://gist.github.com/vxhviet/9c4a522921ad857406033c4125f343a5 here].&lt;br /&gt;
&lt;br /&gt;
==== Gitflow ====&lt;br /&gt;
I was a die-hard believer in gitflow for a while.  It&#039;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]...&lt;br /&gt;
[[File:Git for nice release planning.png]]&lt;br /&gt;
&lt;br /&gt;
=== LFS ===&lt;br /&gt;
Just don&#039;t use it.  It&#039;s shite.  If you get stuck working with a repo that requires it, and you are using ssh on linux which just won&#039;t work with LFS... you will probably end up with a damaged repo.  Fix it with this:&lt;br /&gt;
 git read-tree HEAD &amp;amp;&amp;amp; GIT_LFS_SKIP_SMUDGE=1 git checkout -f HEAD&lt;br /&gt;
After that, use &#039;&#039;&#039;GIT_LFS_SKIP_SMUDGE=1&#039;&#039;&#039; during any git command:&lt;br /&gt;
 GIT_LFS_SKIP_SMUDGE=1 git pull # etc.&lt;br /&gt;
&lt;br /&gt;
=== My git pages (older) ===&lt;br /&gt;
[[Track your changes to an open-source project with git]]&lt;br /&gt;
&lt;br /&gt;
[[Using git on Windows]]&lt;br /&gt;
&lt;br /&gt;
[[Portable git]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Git&amp;diff=7929</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Git&amp;diff=7929"/>
		<updated>2026-01-10T00:14:12Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== TASKS ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set up a new shitcutter project&lt;br /&gt;
|-&lt;br /&gt;
| Setting up a new project:&lt;br /&gt;
* Create the gitlab project with repo support.&lt;br /&gt;
* Grab the Clone with SSH line&lt;br /&gt;
* Go to morosoph parent folder and paste the git line, adding --bare and --shared, and capitalizing as desired, eg:&lt;br /&gt;
 git clone --shared --bare git@shitcutter.com:the-digital-age/teamtunes/teamtunes-website.git TeamTunes-website.git&lt;br /&gt;
* Configure the bare repo to push to upstream on receive, just copy a hook, eg:&lt;br /&gt;
  🤔 m@morosoph  [~/development/thedigitalage/TeamTunes/TeamTunes-android.git] cp ../TeamTunes-iOS.git/hooks/post-receive hooks/&lt;br /&gt;
Ensure that the hook remote name (typically sc) matches config remote name (typically origin).&lt;br /&gt;
* Go to client and clone:&lt;br /&gt;
 TeamTunes] git clone morosoph:development/thedigitalage/TeamTunes/TeamTunes-website.git&lt;br /&gt;
* Add code and push!&lt;br /&gt;
&lt;br /&gt;
old dumb notes:&lt;br /&gt;
&lt;br /&gt;
* Create the gitlab project with repo support.  Go to Settings &amp;gt; Repository &amp;gt; Protected branches and enable &amp;quot;Allowed to force push&amp;quot;.&lt;br /&gt;
* Create a new shared bare repo on LAN.&lt;br /&gt;
* Configure the bare repo to have the gitlab repo as upstream.&lt;br /&gt;
 git remote add sc git@shitcutter.com:the-digital-age/teamtunes/teamtunes-android.git&lt;br /&gt;
 git fetch&lt;br /&gt;
* Configure the bare repo to push to upstream on receive:&lt;br /&gt;
  🤔 m@morosoph  [~/development/thedigitalage/TeamTunes/TeamTunes-android.git] cp ../TeamTunes-iOS.git/hooks/post-receive hooks/&lt;br /&gt;
* Clone shared-bare repo to a client.&lt;br /&gt;
 git clone morosoph:development/thedigitalage/TeamTunes/TeamTunes-android.git&lt;br /&gt;
* Create a main branch on the client.  SADLY YOU HAVE TO COMMIT SOMETHING.  What bs, git...&lt;br /&gt;
 git branch -M main&lt;br /&gt;
 git touch readme.txt&lt;br /&gt;
 git add readme.txt&lt;br /&gt;
 git commit -a -m &amp;quot;Init&amp;quot;&lt;br /&gt;
* Force-push the branch from client to bare repo, it should go all the way to shitcutter:&lt;br /&gt;
 git push -uf main&lt;br /&gt;
* Go back to the gitlab project &amp;gt; Settings &amp;gt; Repository &amp;gt; Protected branches and disable &amp;quot;Allowed to force push&amp;quot;.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! New shared central bare repo&lt;br /&gt;
|-&lt;br /&gt;
| On central server (aka morosoph):&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git init --bare --shared mynewthang.git&lt;br /&gt;
On development box&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git clone morosoph:development/mynewthang.git&lt;br /&gt;
 # this will create a new empty repo with no branch yet&lt;br /&gt;
 # TO CREATE MASTER BRANCH (this is the only way):&lt;br /&gt;
 # create files, git add, git commit, git push&lt;br /&gt;
Back on bitpost&lt;br /&gt;
 git clone mynewthang.git # to create a working copy on server, if desired&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! create shared central repo for existing code&lt;br /&gt;
|-&lt;br /&gt;
| Create a bare repo with .git suffix&lt;br /&gt;
 git init --bare --shared mything.git&lt;br /&gt;
Go to existing code and clone the repo next to it, with a temp name.  &lt;br /&gt;
Move .git into the existing code.&lt;br /&gt;
Add code, add a .gitignore as needed, and you&#039;re all set.&lt;br /&gt;
 cd mything/..&lt;br /&gt;
 git clone (bare-repo-host-and-path)mything.git mything-temp&lt;br /&gt;
 mv mything-temp/.git mything/&lt;br /&gt;
 rm -rf mything-temp&lt;br /&gt;
 cd mything&lt;br /&gt;
 code .gitignore # as needed&lt;br /&gt;
 git add (whatever you want to track)&lt;br /&gt;
 git commit -a -m &amp;quot;init repo&amp;quot; &amp;amp;&amp;amp; git push&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fetch a branch from remote without checking it out&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are rebasing a feature branch.&lt;br /&gt;
 git fetch origin develop:develop&lt;br /&gt;
You would think &amp;lt;code&amp;gt;git fetch --all&amp;lt;/code&amp;gt; would do it but does not (it fetches the active branch from &#039;&#039;all origins&#039;&#039; - seriously wtf, who ever wants THAT??).&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Completely reset an out-of-sync branch to 100% match the remote&lt;br /&gt;
|-&lt;br /&gt;
| 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:&lt;br /&gt;
 git reset --hard origin/thebranchname&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default branch of a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| If you want the default branch of a bare repo to be something other than master:&lt;br /&gt;
 git branch&lt;br /&gt;
  * master&lt;br /&gt;
    moodboom-quick-http&lt;br /&gt;
 git symbolic-ref HEAD refs/heads/moodboom-quick-http&lt;br /&gt;
 git branch&lt;br /&gt;
    master&lt;br /&gt;
  * moodboom-quick-http&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Get a file from another branch&lt;br /&gt;
|-&lt;br /&gt;
| Grab the latest version in otherBranch and dump it into your current branch main:&lt;br /&gt;
 git switch main&lt;br /&gt;
 git restore --source otherBranch -- myfile.js&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Find a file across branches&lt;br /&gt;
|-&lt;br /&gt;
| It&#039;s clunky, two steps, and you have to glob out the whole fucking name:&lt;br /&gt;
 # get the commits that involved the filename&lt;br /&gt;
 git log --all -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # even better, get the filenames too, and see if it was added or removed:&lt;br /&gt;
 git log --all --stat -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # now find the branch with one of those commits:&lt;br /&gt;
 git branch -a --contains #commithash#&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gitflow&lt;br /&gt;
|-&lt;br /&gt;
| Gitflow is awesome, using it myself and everywhere I work these days (2020).&lt;br /&gt;
* Devs work out of develop branch&lt;br /&gt;
* Devs create feature branches off develop for any decent-sized work&lt;br /&gt;
* Once develop is stable and you are ready for a release:&lt;br /&gt;
 git tag -a -m &amp;quot;#MAJOR#.#MINOR#&amp;quot;.0 #MAJOR#.#MINOR#.0&lt;br /&gt;
 git checkout -b release/release_#MAJOR#.#MINOR#&lt;br /&gt;
 git push --set-upstream origin release_#MAJOR#.#MINOR#&lt;br /&gt;
 git checkout master &amp;amp;&amp;amp; git merge release/release_#MAJOR#.#MINOR# &amp;amp;&amp;amp; git push&lt;br /&gt;
 git checkout develop # and get back to it!&lt;br /&gt;
* Do hotfixes as needed in release branch, tagged #MAJOR#.#MINOR#.++, merged back into master and develop&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Interactive rebase with squash&lt;br /&gt;
|-&lt;br /&gt;
| Excellent to do when on your own feature branch.  Illegal to do if branch is shared AT ALL!&lt;br /&gt;
 git rebase -i myparentbranch&lt;br /&gt;
 # work through squash and merge - gitlens may help with squash if you use vscode for EDITOR&lt;br /&gt;
 git push -f&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Push any branch from bare to origin&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are force-pushing a branch rebase.&lt;br /&gt;
 git push [-f] origin mybranch:mybranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstream config example&lt;br /&gt;
|-&lt;br /&gt;
| If you edit a file in GitLab, you may need to pull it from remote &amp;quot;gitlab&amp;quot; and push it to remote &amp;quot;sc&amp;quot;, like this:&lt;br /&gt;
 git fetch gitlab develop:develop&lt;br /&gt;
 git push sc&lt;br /&gt;
This assumes you have something like the following in your config:&lt;br /&gt;
 [remote &amp;quot;sc&amp;quot;]&lt;br /&gt;
        url = git@shitcutter.com:the-digital-age/rad-scripts.git&lt;br /&gt;
        fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;github.com&amp;quot;]&lt;br /&gt;
	url = git@github.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;gitlab.com&amp;quot;]&lt;br /&gt;
	url = git@gitlab.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merging conflicts after diverging&lt;br /&gt;
|-&lt;br /&gt;
| Revert local changes in a file to HEAD&lt;br /&gt;
 git checkout -- path/to/file.txt&lt;br /&gt;
Discard ALL LOCAL COMMITS and get the (possibly diverged) remote instead&lt;br /&gt;
 git reset --hard origin/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and push a feature branch&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
 git checkout -b feature/whiz-bang&lt;br /&gt;
 &lt;br /&gt;
 # Do this ONCE: git config --global push.default current&lt;br /&gt;
 # From then on:&lt;br /&gt;
 git push -u&lt;br /&gt;
 &lt;br /&gt;
 # OR, if you don&#039;t want the config, you have to be more specific:&lt;br /&gt;
 # git push -u origin feature/whiz-bang&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab GITFLOW fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
&lt;br /&gt;
This is very easy if you have left the master branch alone for the parent&#039;s commits, and keep your add-on commits in a release-x.x branch, as we have for SWS and SWSS.&lt;br /&gt;
&lt;br /&gt;
 cdl&lt;br /&gt;
 # Clone local repo directly from GitLab (already done on cobra)&lt;br /&gt;
 git clone git@gitlab.com:moodboom/Simple-Web-Server.git SWS-gitlab-moodboom&lt;br /&gt;
 cd SWS-gitlab-moodboom&lt;br /&gt;
 # make sure master is checked out&lt;br /&gt;
 git branch&lt;br /&gt;
 # add parent as remote&lt;br /&gt;
 git remote add ole-upstream git@gitlab.com:eidheim/Simple-Web-Server.git&lt;br /&gt;
 git fetch ole-upstream&lt;br /&gt;
 git rebase ole-upstream/master&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
You can now delete the fresh clone, it has done its job.  Or leave it for ease-of-use for next rebase.&lt;br /&gt;
&lt;br /&gt;
Now update your bare repo on bitpost, to keep things in sync.&lt;br /&gt;
 git fetch origin master:master -f&lt;br /&gt;
&lt;br /&gt;
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&#039;s what you want)  It is the gitflow way!&lt;br /&gt;
&lt;br /&gt;
Push your new branch to bare, then push bare to GitLab via something like:&lt;br /&gt;
 git push --set-upstream origin release/abt-0.0.3&lt;br /&gt;
&lt;br /&gt;
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!)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://gitlab.com/someauthor/theprojectiforked&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
If you haven&#039;t done so, in GitLab, go to [https://gitlab.com/moodboom/Simple-WebSocket-Server/-/settings/repository#js-protected-branches-settings the &amp;quot;Protected Branch&amp;quot; settings] and remove protection from master - it&#039;s just a fact that you&#039;re going to need to force-push to master.&lt;br /&gt;
&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitLab. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
You will want to force-fetch to update the bare repo you may have on bitpost, DO THIS NOW or you will screw things up badly later:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git fetch origin master:master -f&lt;br /&gt;
You should also force-update ALL your dev repos, NOW, for the same reason:&lt;br /&gt;
 git reset --hard HEAD^^^^^^ &amp;amp;&amp;amp; git pull&lt;br /&gt;
NOTE that you may need to remove a remote-tracking branch if you don&#039;t need it any more.  It&#039;s stupidly painful to get right, eg:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git branch -rd eidheim/Simple-WebSocket-Server/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitHub fork&lt;br /&gt;
|-&lt;br /&gt;
| From [http://stackoverflow.com/a/7244456/717274 so...]&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://github.com/someauthor/theprojectiforked.git&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitHub. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
Now master has the latest commits from the fork origin.  You can rebase onto it, if you&#039;ve been working in a branch (good):&lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git rebase master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Clone a bare repo (eg github, gitlab, bb) into a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Say you want a bare repo to be shared by all your dev environments, but you need to push/pull THAT from a central bare repo, too.&lt;br /&gt;
 git clone --bare --shared git@bitbucket.org:equityshift/es-demo.git&lt;br /&gt;
 cd es-demo.git&lt;br /&gt;
 git config remote.origin.fetch &amp;quot;+*:*&amp;quot;&lt;br /&gt;
 git fetch --all&lt;br /&gt;
I was surprised that this was difficult at all, and may still have some lessons to learn...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch on server, pull to client&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 # ON CENTRAL SERVER&lt;br /&gt;
 git checkout master # as needed; we are assuming that master is clean enough as a starting point&lt;br /&gt;
 git checkout -b mynewbranchy&lt;br /&gt;
 &lt;br /&gt;
 # HOWEVER, use this instead if you need a new &amp;quot;clean&amp;quot; repo and even master is dirty...&lt;br /&gt;
 # You need the rm because git &amp;quot;leaves your working folder intact&amp;quot;.&lt;br /&gt;
 git checkout --orphan mynewbranchy&lt;br /&gt;
 git rm -rf .&lt;br /&gt;
 &lt;br /&gt;
 # ON CLIENT&lt;br /&gt;
 git pull&lt;br /&gt;
 git checkout -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
 # if files are in the way from the previously checked-out branch, you can force it...&lt;br /&gt;
 git checkout -f -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merge changes in a single file&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/11593308/717274 here].  &lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git checkout --patch develop my/single/file.cpp&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove old branches&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/23961231/717274 here].  &lt;br /&gt;
Remote:&lt;br /&gt;
 git push origin --delete &amp;lt;branch&amp;gt;&lt;br /&gt;
Local:&lt;br /&gt;
 git branch -d &amp;lt;branch&amp;gt;&lt;br /&gt;
 git fetch &amp;lt;remote&amp;gt; --prune # Delete multiple obsolete tracking branches&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Work with two local repos&lt;br /&gt;
|-&lt;br /&gt;
| Set up a remote, then fetch it as master.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout --track otherplace/master # or other branch as needed; this creates the branch and sets remote in one step, cool&lt;br /&gt;
Set up a remote, then fetch it into a non-master branch, and push it to the active origin.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout otherplace/master # creates it detached, good because we need to name the new branch something other than master&lt;br /&gt;
 git checkout -b new_otherplace_branchname # creates new local branch with a good name&lt;br /&gt;
 git push --set-upstream origin new_otherplace_branchname # takes the branch from the OLD origin and pushes it to the ACTIVE origin, cool!&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Pull when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
| This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo:&lt;br /&gt;
 git fetch --all&lt;br /&gt;
 git reset --hard origin/mymatchingbranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
   git checkout -b bj143 origin/bj143&lt;br /&gt;
      git : error: The following untracked working tree files would be overwritten by checkout:&lt;br /&gt;
      (etc)&lt;br /&gt;
   &lt;br /&gt;
   TOTAL PURGE FIX (too much):&lt;br /&gt;
      git clean  -d  -fn &amp;quot;&amp;quot;&lt;br /&gt;
         -d dirs too&lt;br /&gt;
         -f force, required&lt;br /&gt;
         -x include ignored files (don&#039;t use this)&lt;br /&gt;
         -n dry run&lt;br /&gt;
   &lt;br /&gt;
   BEST FIX (just overwrite what is in the way):&lt;br /&gt;
      git checkout -f -b bj143 origin/bj143&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Recreate repo&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git clone ssh://m@thedigitalmachine.com/home/m/development/thedigitalage/ampache-with-hangthedj-module&lt;br /&gt;
 cd ampache-with-hangthedj-module&lt;br /&gt;
 git checkout -b daily_grind origin/daily_grind&lt;br /&gt;
If you already have the daily_grind branches and just need to connect them:&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Connect to origin after the fact&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git remote add origin ssh:// m@bitpost.com/home/m/development/logs&lt;br /&gt;
 git fetch&lt;br /&gt;
     From ssh:// bitpost/home/m/development/logs&lt;br /&gt;
      * [new branch]      daily_grind -&amp;gt; origin/daily_grind&lt;br /&gt;
      * [new branch]      master     -&amp;gt; origin/master&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git branch -u origin/master master&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ignore local and remote changes to a file &lt;br /&gt;
|-&lt;br /&gt;
| This is helpful for conf files that need local-specific modifications that shouldn&#039;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].&lt;br /&gt;
&lt;br /&gt;
        PREVENT COMMIT OF CHANGES TO A LOCAL FILE&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
        git update-index --skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        RESET TO GET CHANGES AGAIN&lt;br /&gt;
        --------------------------&lt;br /&gt;
        git update-index --no-skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        LIST SKIPPED FILES&lt;br /&gt;
        ------------------&lt;br /&gt;
        git ls-files -v . | grep ^S&lt;br /&gt;
        S app/views/_partials/jsIncludes.scala.html&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Replace name and email of last commit&lt;br /&gt;
|-&lt;br /&gt;
| Reset the name and email of the last commit, when you realize you forgot to set them first:&lt;br /&gt;
 git commit --amend --author=&amp;quot;First Last &amp;lt;email&amp;gt;&amp;quot; --no-edit&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Simple tagging (when not using git-sync)&lt;br /&gt;
|-&lt;br /&gt;
| To add and push a tag to HEAD:&lt;br /&gt;
 git tag -a 1.2.0 -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
To add and push a tag attached to a commit with current time as timestamp:&lt;br /&gt;
 git tag -a 1.2.0 1bc92e2f -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
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]:&lt;br /&gt;
 # Set the HEAD to the old commit that we want to tag&lt;br /&gt;
 git checkout 9fceb02&lt;br /&gt;
 &lt;br /&gt;
 # temporarily set the date to the date of the HEAD commit, and add the tag&lt;br /&gt;
 GIT_COMMITTER_DATE=&amp;quot;$(git show --format=%aD | head -1)&amp;quot; \&lt;br /&gt;
 git tag -a v1.2 -m&amp;quot;v1.2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # push to origin&lt;br /&gt;
 git push origin --tags&lt;br /&gt;
 &lt;br /&gt;
 # set HEAD back to whatever you want it to be&lt;br /&gt;
 git checkout master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove a tag&lt;br /&gt;
|-&lt;br /&gt;
| This has a long clumsy history, but these instructions should be good into the future.&lt;br /&gt;
&lt;br /&gt;
To remove remote tag(s):&lt;br /&gt;
 git push --delete origin tag YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
Remove tag(s) locally:&lt;br /&gt;
  git tag -d YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Changing branches in a project with submodules&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 # always reset the @*$ submodules to proper commits&lt;br /&gt;
 git checkout develop &amp;amp;&amp;amp; git submodule update&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Hard-reset a misbehaving submodule to parent commit version&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git submodule deinit -f .&lt;br /&gt;
 git submodule update --init&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CONFIGURATION ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set name and email&lt;br /&gt;
|-&lt;br /&gt;
| Globally on one machine (note the machine name at end of user name):&lt;br /&gt;
 git config --global user.email m@thedigitalmachine.com;  git config user.name &amp;quot;Michael Behrns-Miller [cast]&amp;quot;&lt;br /&gt;
Override for a repository:&lt;br /&gt;
 git config user.email mbm@equityshift.io;  git config user.name &amp;quot;MBM [cast]&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default root to main not master&lt;br /&gt;
|-&lt;br /&gt;
| I love the idea of a kinder root name, suck it up alt-right down-punchers, lol.&lt;br /&gt;
Configure it to always happen:&lt;br /&gt;
 git config --global init.defaultBranch main&lt;br /&gt;
Fix it for a newly initialized repository:&lt;br /&gt;
 git branch -m main&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - ONLY PUSH CURRENT doh&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.default current&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - always create remote of a local branch name on push&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.autoSetupRemote true&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - allow push -f&lt;br /&gt;
|-&lt;br /&gt;
| When did it become necessary to configure the upstream to allow this?&lt;br /&gt;
 git config receive.denyNonFastForwards false # to allow git push -f&lt;br /&gt;
 git config receive.denyNonFastForwards true # to turn that back off, good practice i guess&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Visual difftool and mergetool setup&lt;br /&gt;
|-&lt;br /&gt;
| Meld is purdy, let&#039;s kick its tires.  Hope it actually works...&lt;br /&gt;
 git config --global diff.tool meld&lt;br /&gt;
 git config --global merge.tool meld&lt;br /&gt;
 git config --global --add difftool.prompt false&lt;br /&gt;
I used to set up kdiff3 manually, like this... (gross)&lt;br /&gt;
* LINUX - put this in ~/.gitconfig&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 &lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* WINDOZE&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* LINUX Before - What a ridiculous pita... copy this into .git/config...&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert to a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Start with a normal git repo via [git init]; add your files, get it all set up.  Then do this:&lt;br /&gt;
 cd repo&lt;br /&gt;
Now you can copy-paste this...&lt;br /&gt;
 mv .git .. &amp;amp;&amp;amp; rm -fr *&lt;br /&gt;
 mv ../.git .&lt;br /&gt;
 mv .git/* .&lt;br /&gt;
 rmdir .git&lt;br /&gt;
 git config --bool core.bare true&lt;br /&gt;
 cd ..&lt;br /&gt;
Don&#039;t copy/paste these, you need to change repo name...&lt;br /&gt;
 mv repo repo.git # rename it for clarity&lt;br /&gt;
 git clone repo.git # (optional, if you want a live repo on the server where you have the bare repo)&lt;br /&gt;
Then you can clean up old branches like daily and daily_grind, as needed.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert bare to a mirror of remote (github, facebook, etc)&lt;br /&gt;
|-&lt;br /&gt;
| You need a bare mirror repo if you want to take someone else&#039;s repo and create your own bare to work from.&lt;br /&gt;
If you did NOT specify --mirror when you first created the bare repo, you can convert to a mirror by adding these last two lines to config, underneath url:&lt;br /&gt;
 [remote &amp;quot;origin&amp;quot;]&lt;br /&gt;
    url = git@github.com:facebook/proxygen.git&lt;br /&gt;
    fetch = +refs/*:refs/*&lt;br /&gt;
    mirror = true&lt;br /&gt;
Now you can fetch from the bare repo:&lt;br /&gt;
 git fetch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create merge-to command&lt;br /&gt;
|-&lt;br /&gt;
| Add this handy alias command to all git repos&#039; .config file...&lt;br /&gt;
 [alias]&lt;br /&gt;
     merge-to = &amp;quot;!gitmergeto() { export tmp_branch=`git branch | grep &#039;* &#039; | tr -d &#039;* &#039;` &amp;amp;&amp;amp; git checkout $1 &amp;amp;&amp;amp; git merge $tmp_branch &amp;amp;&amp;amp; git checkout $tmp_branch; unset tmp_branch; }; gitmergeto&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix github diverge from local bare repo following README.md edit&lt;br /&gt;
|-&lt;br /&gt;
| Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling.&lt;br /&gt;
Fixing it is a PAIN in the ASS, you have to create a new local repo and pull github into that, pull in from your other local repo, push to github, pull to your bare... &lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git quick-http-with-readme-conflict&lt;br /&gt;
 git remote add local ../quick-http&lt;br /&gt;
 git fetch local&lt;br /&gt;
 git merge local/master # merge in changes, likely trivial&lt;br /&gt;
 git push # pushes back to github&lt;br /&gt;
 cd ..&lt;br /&gt;
 mv quick-http.git quick-http.git__gone-out-of-sync-fu-github-readme-editor&lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git --bare&lt;br /&gt;
 cp quick-http.git__gone-out-of-sync-fu-github-readme-editor/config quick-http.git/&lt;br /&gt;
And that MIGHT get you on your way... but I would no longer trust ANY of your local repos...&lt;br /&gt;
This is a serious pita.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows configure notepad++ editor&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 git config --global core.editor &amp;quot;&#039;C:/Program Files (x86)/Notepad++/notepad++.exe&#039; -multiInst -notabbar -nosession -noPlugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstreams&lt;br /&gt;
|-&lt;br /&gt;
| Use this to cause AUTOMATIC push/pull to a second origin:&lt;br /&gt;
 git remote set-url origin --push --add user1@repo1&lt;br /&gt;
 git remote set-url origin --push --add user2@repo2&lt;br /&gt;
 git remote -v show&lt;br /&gt;
Leave out --push if you want to pull as well... but I&#039;d be careful, it&#039;s better if code is changed in one client with this config, and then pushed to the multiple origins from there.  Otherwise, things are GOING TO GET SYNCY-STINKY.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Git branching strategies ===&lt;br /&gt;
==== Simplified Gitflow ====&lt;br /&gt;
This is awesome, tight, and well-capable of handling any app with a single primary release (like a website).&lt;br /&gt;
                         RELEASE TAG&lt;br /&gt;
 o----------------------------o-----------------o------------o------&amp;gt; MASTER&lt;br /&gt;
  \                          /  \                \----------/ HOTFIX&lt;br /&gt;
   \                        /    \                          \&lt;br /&gt;
    \----------------------/      \--------------------o-----o------&amp;gt; DEVELOP&lt;br /&gt;
                                   \                  /&lt;br /&gt;
                                    \----------------/ FEATURE&lt;br /&gt;
&lt;br /&gt;
Read more [https://medium.com/goodtogoat/simplified-git-flow-5dc37ba76ea8 here] and [https://gist.github.com/vxhviet/9c4a522921ad857406033c4125f343a5 here].&lt;br /&gt;
&lt;br /&gt;
==== Gitflow ====&lt;br /&gt;
I was a die-hard believer in gitflow for a while.  It&#039;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]...&lt;br /&gt;
[[File:Git for nice release planning.png]]&lt;br /&gt;
&lt;br /&gt;
=== LFS ===&lt;br /&gt;
Just don&#039;t use it.  It&#039;s shite.  If you get stuck working with a repo that requires it, and you are using ssh on linux which just won&#039;t work with LFS... you will probably end up with a damaged repo.  Fix it with this:&lt;br /&gt;
 git read-tree HEAD &amp;amp;&amp;amp; GIT_LFS_SKIP_SMUDGE=1 git checkout -f HEAD&lt;br /&gt;
After that, use &#039;&#039;&#039;GIT_LFS_SKIP_SMUDGE=1&#039;&#039;&#039; during any git command:&lt;br /&gt;
 GIT_LFS_SKIP_SMUDGE=1 git pull # etc.&lt;br /&gt;
&lt;br /&gt;
=== My git pages (older) ===&lt;br /&gt;
[[Track your changes to an open-source project with git]]&lt;br /&gt;
&lt;br /&gt;
[[Using git on Windows]]&lt;br /&gt;
&lt;br /&gt;
[[Portable git]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Git&amp;diff=7928</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Git&amp;diff=7928"/>
		<updated>2026-01-09T22:29:51Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== TASKS ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set up a new shitcutter project&lt;br /&gt;
|-&lt;br /&gt;
| This is my development setup:&lt;br /&gt;
 gitlab-repo &amp;lt; shared-bare-repo &amp;lt; lan-clients&lt;br /&gt;
&lt;br /&gt;
My shared-bare-repos are my source of truth.  I don&#039;t want it to be gitlab, that just gets in the way when I&#039;m on my LAN.  But I do push code up there when I want to share with others.&lt;br /&gt;
&lt;br /&gt;
Setting up a new project:&lt;br /&gt;
* Create the gitlab project with repo support.&lt;br /&gt;
* Grab the Clone with SSH line&lt;br /&gt;
* Go to morosoph parent folder and paste the git line, adding --bare and --shared, and capitalizing as desired, eg:&lt;br /&gt;
 git clone --shared --bare git@shitcutter.com:the-digital-age/teamtunes/teamtunes-website.git TeamTunes-website.git&lt;br /&gt;
* Go to client and clone:&lt;br /&gt;
 TeamTunes] git clone morosoph:development/thedigitalage/TeamTunes/TeamTunes-website.git&lt;br /&gt;
* Add code and push!&lt;br /&gt;
&lt;br /&gt;
old dumb notes:&lt;br /&gt;
&lt;br /&gt;
* Create the gitlab project with repo support.  Go to Settings &amp;gt; Repository &amp;gt; Protected branches and enable &amp;quot;Allowed to force push&amp;quot;.&lt;br /&gt;
* Create a new shared bare repo on LAN.&lt;br /&gt;
* Configure the bare repo to have the gitlab repo as upstream.&lt;br /&gt;
 git remote add sc git@shitcutter.com:the-digital-age/teamtunes/teamtunes-android.git&lt;br /&gt;
 git fetch&lt;br /&gt;
* Configure the bare repo to push to upstream on receive:&lt;br /&gt;
  🤔 m@morosoph  [~/development/thedigitalage/TeamTunes/TeamTunes-android.git] cp ../TeamTunes-iOS.git/hooks/post-receive hooks/&lt;br /&gt;
* Clone shared-bare repo to a client.&lt;br /&gt;
 git clone morosoph:development/thedigitalage/TeamTunes/TeamTunes-android.git&lt;br /&gt;
* Create a main branch on the client.  SADLY YOU HAVE TO COMMIT SOMETHING.  What bs, git...&lt;br /&gt;
 git branch -M main&lt;br /&gt;
 git touch readme.txt&lt;br /&gt;
 git add readme.txt&lt;br /&gt;
 git commit -a -m &amp;quot;Init&amp;quot;&lt;br /&gt;
* Force-push the branch from client to bare repo, it should go all the way to shitcutter:&lt;br /&gt;
 git push -uf main&lt;br /&gt;
* Go back to the gitlab project &amp;gt; Settings &amp;gt; Repository &amp;gt; Protected branches and disable &amp;quot;Allowed to force push&amp;quot;.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! New shared central bare repo&lt;br /&gt;
|-&lt;br /&gt;
| On central server (aka morosoph):&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git init --bare --shared mynewthang.git&lt;br /&gt;
On development box&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git clone morosoph:development/mynewthang.git&lt;br /&gt;
 # this will create a new empty repo with no branch yet&lt;br /&gt;
 # TO CREATE MASTER BRANCH (this is the only way):&lt;br /&gt;
 # create files, git add, git commit, git push&lt;br /&gt;
Back on bitpost&lt;br /&gt;
 git clone mynewthang.git # to create a working copy on server, if desired&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! create shared central repo for existing code&lt;br /&gt;
|-&lt;br /&gt;
| Create a bare repo with .git suffix&lt;br /&gt;
 git init --bare --shared mything.git&lt;br /&gt;
Go to existing code and clone the repo next to it, with a temp name.  &lt;br /&gt;
Move .git into the existing code.&lt;br /&gt;
Add code, add a .gitignore as needed, and you&#039;re all set.&lt;br /&gt;
 cd mything/..&lt;br /&gt;
 git clone (bare-repo-host-and-path)mything.git mything-temp&lt;br /&gt;
 mv mything-temp/.git mything/&lt;br /&gt;
 rm -rf mything-temp&lt;br /&gt;
 cd mything&lt;br /&gt;
 code .gitignore # as needed&lt;br /&gt;
 git add (whatever you want to track)&lt;br /&gt;
 git commit -a -m &amp;quot;init repo&amp;quot; &amp;amp;&amp;amp; git push&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fetch a branch from remote without checking it out&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are rebasing a feature branch.&lt;br /&gt;
 git fetch origin develop:develop&lt;br /&gt;
You would think &amp;lt;code&amp;gt;git fetch --all&amp;lt;/code&amp;gt; would do it but does not (it fetches the active branch from &#039;&#039;all origins&#039;&#039; - seriously wtf, who ever wants THAT??).&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Completely reset an out-of-sync branch to 100% match the remote&lt;br /&gt;
|-&lt;br /&gt;
| 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:&lt;br /&gt;
 git reset --hard origin/thebranchname&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default branch of a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| If you want the default branch of a bare repo to be something other than master:&lt;br /&gt;
 git branch&lt;br /&gt;
  * master&lt;br /&gt;
    moodboom-quick-http&lt;br /&gt;
 git symbolic-ref HEAD refs/heads/moodboom-quick-http&lt;br /&gt;
 git branch&lt;br /&gt;
    master&lt;br /&gt;
  * moodboom-quick-http&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Get a file from another branch&lt;br /&gt;
|-&lt;br /&gt;
| Grab the latest version in otherBranch and dump it into your current branch main:&lt;br /&gt;
 git switch main&lt;br /&gt;
 git restore --source otherBranch -- myfile.js&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Find a file across branches&lt;br /&gt;
|-&lt;br /&gt;
| It&#039;s clunky, two steps, and you have to glob out the whole fucking name:&lt;br /&gt;
 # get the commits that involved the filename&lt;br /&gt;
 git log --all -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # even better, get the filenames too, and see if it was added or removed:&lt;br /&gt;
 git log --all --stat -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # now find the branch with one of those commits:&lt;br /&gt;
 git branch -a --contains #commithash#&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gitflow&lt;br /&gt;
|-&lt;br /&gt;
| Gitflow is awesome, using it myself and everywhere I work these days (2020).&lt;br /&gt;
* Devs work out of develop branch&lt;br /&gt;
* Devs create feature branches off develop for any decent-sized work&lt;br /&gt;
* Once develop is stable and you are ready for a release:&lt;br /&gt;
 git tag -a -m &amp;quot;#MAJOR#.#MINOR#&amp;quot;.0 #MAJOR#.#MINOR#.0&lt;br /&gt;
 git checkout -b release/release_#MAJOR#.#MINOR#&lt;br /&gt;
 git push --set-upstream origin release_#MAJOR#.#MINOR#&lt;br /&gt;
 git checkout master &amp;amp;&amp;amp; git merge release/release_#MAJOR#.#MINOR# &amp;amp;&amp;amp; git push&lt;br /&gt;
 git checkout develop # and get back to it!&lt;br /&gt;
* Do hotfixes as needed in release branch, tagged #MAJOR#.#MINOR#.++, merged back into master and develop&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Interactive rebase with squash&lt;br /&gt;
|-&lt;br /&gt;
| Excellent to do when on your own feature branch.  Illegal to do if branch is shared AT ALL!&lt;br /&gt;
 git rebase -i myparentbranch&lt;br /&gt;
 # work through squash and merge - gitlens may help with squash if you use vscode for EDITOR&lt;br /&gt;
 git push -f&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Push any branch from bare to origin&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are force-pushing a branch rebase.&lt;br /&gt;
 git push [-f] origin mybranch:mybranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstream config example&lt;br /&gt;
|-&lt;br /&gt;
| If you edit a file in GitLab, you may need to pull it from remote &amp;quot;gitlab&amp;quot; and push it to remote &amp;quot;sc&amp;quot;, like this:&lt;br /&gt;
 git fetch gitlab develop:develop&lt;br /&gt;
 git push sc&lt;br /&gt;
This assumes you have something like the following in your config:&lt;br /&gt;
 [remote &amp;quot;sc&amp;quot;]&lt;br /&gt;
        url = git@shitcutter.com:the-digital-age/rad-scripts.git&lt;br /&gt;
        fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;github.com&amp;quot;]&lt;br /&gt;
	url = git@github.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;gitlab.com&amp;quot;]&lt;br /&gt;
	url = git@gitlab.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merging conflicts after diverging&lt;br /&gt;
|-&lt;br /&gt;
| Revert local changes in a file to HEAD&lt;br /&gt;
 git checkout -- path/to/file.txt&lt;br /&gt;
Discard ALL LOCAL COMMITS and get the (possibly diverged) remote instead&lt;br /&gt;
 git reset --hard origin/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and push a feature branch&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
 git checkout -b feature/whiz-bang&lt;br /&gt;
 &lt;br /&gt;
 # Do this ONCE: git config --global push.default current&lt;br /&gt;
 # From then on:&lt;br /&gt;
 git push -u&lt;br /&gt;
 &lt;br /&gt;
 # OR, if you don&#039;t want the config, you have to be more specific:&lt;br /&gt;
 # git push -u origin feature/whiz-bang&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab GITFLOW fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
&lt;br /&gt;
This is very easy if you have left the master branch alone for the parent&#039;s commits, and keep your add-on commits in a release-x.x branch, as we have for SWS and SWSS.&lt;br /&gt;
&lt;br /&gt;
 cdl&lt;br /&gt;
 # Clone local repo directly from GitLab (already done on cobra)&lt;br /&gt;
 git clone git@gitlab.com:moodboom/Simple-Web-Server.git SWS-gitlab-moodboom&lt;br /&gt;
 cd SWS-gitlab-moodboom&lt;br /&gt;
 # make sure master is checked out&lt;br /&gt;
 git branch&lt;br /&gt;
 # add parent as remote&lt;br /&gt;
 git remote add ole-upstream git@gitlab.com:eidheim/Simple-Web-Server.git&lt;br /&gt;
 git fetch ole-upstream&lt;br /&gt;
 git rebase ole-upstream/master&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
You can now delete the fresh clone, it has done its job.  Or leave it for ease-of-use for next rebase.&lt;br /&gt;
&lt;br /&gt;
Now update your bare repo on bitpost, to keep things in sync.&lt;br /&gt;
 git fetch origin master:master -f&lt;br /&gt;
&lt;br /&gt;
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&#039;s what you want)  It is the gitflow way!&lt;br /&gt;
&lt;br /&gt;
Push your new branch to bare, then push bare to GitLab via something like:&lt;br /&gt;
 git push --set-upstream origin release/abt-0.0.3&lt;br /&gt;
&lt;br /&gt;
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!)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://gitlab.com/someauthor/theprojectiforked&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
If you haven&#039;t done so, in GitLab, go to [https://gitlab.com/moodboom/Simple-WebSocket-Server/-/settings/repository#js-protected-branches-settings the &amp;quot;Protected Branch&amp;quot; settings] and remove protection from master - it&#039;s just a fact that you&#039;re going to need to force-push to master.&lt;br /&gt;
&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitLab. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
You will want to force-fetch to update the bare repo you may have on bitpost, DO THIS NOW or you will screw things up badly later:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git fetch origin master:master -f&lt;br /&gt;
You should also force-update ALL your dev repos, NOW, for the same reason:&lt;br /&gt;
 git reset --hard HEAD^^^^^^ &amp;amp;&amp;amp; git pull&lt;br /&gt;
NOTE that you may need to remove a remote-tracking branch if you don&#039;t need it any more.  It&#039;s stupidly painful to get right, eg:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git branch -rd eidheim/Simple-WebSocket-Server/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitHub fork&lt;br /&gt;
|-&lt;br /&gt;
| From [http://stackoverflow.com/a/7244456/717274 so...]&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://github.com/someauthor/theprojectiforked.git&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitHub. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
Now master has the latest commits from the fork origin.  You can rebase onto it, if you&#039;ve been working in a branch (good):&lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git rebase master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Clone a bare repo (eg github, gitlab, bb) into a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Say you want a bare repo to be shared by all your dev environments, but you need to push/pull THAT from a central bare repo, too.&lt;br /&gt;
 git clone --bare --shared git@bitbucket.org:equityshift/es-demo.git&lt;br /&gt;
 cd es-demo.git&lt;br /&gt;
 git config remote.origin.fetch &amp;quot;+*:*&amp;quot;&lt;br /&gt;
 git fetch --all&lt;br /&gt;
I was surprised that this was difficult at all, and may still have some lessons to learn...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch on server, pull to client&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 # ON CENTRAL SERVER&lt;br /&gt;
 git checkout master # as needed; we are assuming that master is clean enough as a starting point&lt;br /&gt;
 git checkout -b mynewbranchy&lt;br /&gt;
 &lt;br /&gt;
 # HOWEVER, use this instead if you need a new &amp;quot;clean&amp;quot; repo and even master is dirty...&lt;br /&gt;
 # You need the rm because git &amp;quot;leaves your working folder intact&amp;quot;.&lt;br /&gt;
 git checkout --orphan mynewbranchy&lt;br /&gt;
 git rm -rf .&lt;br /&gt;
 &lt;br /&gt;
 # ON CLIENT&lt;br /&gt;
 git pull&lt;br /&gt;
 git checkout -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
 # if files are in the way from the previously checked-out branch, you can force it...&lt;br /&gt;
 git checkout -f -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merge changes in a single file&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/11593308/717274 here].  &lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git checkout --patch develop my/single/file.cpp&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove old branches&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/23961231/717274 here].  &lt;br /&gt;
Remote:&lt;br /&gt;
 git push origin --delete &amp;lt;branch&amp;gt;&lt;br /&gt;
Local:&lt;br /&gt;
 git branch -d &amp;lt;branch&amp;gt;&lt;br /&gt;
 git fetch &amp;lt;remote&amp;gt; --prune # Delete multiple obsolete tracking branches&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Work with two local repos&lt;br /&gt;
|-&lt;br /&gt;
| Set up a remote, then fetch it as master.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout --track otherplace/master # or other branch as needed; this creates the branch and sets remote in one step, cool&lt;br /&gt;
Set up a remote, then fetch it into a non-master branch, and push it to the active origin.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout otherplace/master # creates it detached, good because we need to name the new branch something other than master&lt;br /&gt;
 git checkout -b new_otherplace_branchname # creates new local branch with a good name&lt;br /&gt;
 git push --set-upstream origin new_otherplace_branchname # takes the branch from the OLD origin and pushes it to the ACTIVE origin, cool!&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Pull when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
| This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo:&lt;br /&gt;
 git fetch --all&lt;br /&gt;
 git reset --hard origin/mymatchingbranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
   git checkout -b bj143 origin/bj143&lt;br /&gt;
      git : error: The following untracked working tree files would be overwritten by checkout:&lt;br /&gt;
      (etc)&lt;br /&gt;
   &lt;br /&gt;
   TOTAL PURGE FIX (too much):&lt;br /&gt;
      git clean  -d  -fn &amp;quot;&amp;quot;&lt;br /&gt;
         -d dirs too&lt;br /&gt;
         -f force, required&lt;br /&gt;
         -x include ignored files (don&#039;t use this)&lt;br /&gt;
         -n dry run&lt;br /&gt;
   &lt;br /&gt;
   BEST FIX (just overwrite what is in the way):&lt;br /&gt;
      git checkout -f -b bj143 origin/bj143&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Recreate repo&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git clone ssh://m@thedigitalmachine.com/home/m/development/thedigitalage/ampache-with-hangthedj-module&lt;br /&gt;
 cd ampache-with-hangthedj-module&lt;br /&gt;
 git checkout -b daily_grind origin/daily_grind&lt;br /&gt;
If you already have the daily_grind branches and just need to connect them:&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Connect to origin after the fact&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git remote add origin ssh:// m@bitpost.com/home/m/development/logs&lt;br /&gt;
 git fetch&lt;br /&gt;
     From ssh:// bitpost/home/m/development/logs&lt;br /&gt;
      * [new branch]      daily_grind -&amp;gt; origin/daily_grind&lt;br /&gt;
      * [new branch]      master     -&amp;gt; origin/master&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git branch -u origin/master master&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ignore local and remote changes to a file &lt;br /&gt;
|-&lt;br /&gt;
| This is helpful for conf files that need local-specific modifications that shouldn&#039;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].&lt;br /&gt;
&lt;br /&gt;
        PREVENT COMMIT OF CHANGES TO A LOCAL FILE&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
        git update-index --skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        RESET TO GET CHANGES AGAIN&lt;br /&gt;
        --------------------------&lt;br /&gt;
        git update-index --no-skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        LIST SKIPPED FILES&lt;br /&gt;
        ------------------&lt;br /&gt;
        git ls-files -v . | grep ^S&lt;br /&gt;
        S app/views/_partials/jsIncludes.scala.html&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Replace name and email of last commit&lt;br /&gt;
|-&lt;br /&gt;
| Reset the name and email of the last commit, when you realize you forgot to set them first:&lt;br /&gt;
 git commit --amend --author=&amp;quot;First Last &amp;lt;email&amp;gt;&amp;quot; --no-edit&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Simple tagging (when not using git-sync)&lt;br /&gt;
|-&lt;br /&gt;
| To add and push a tag to HEAD:&lt;br /&gt;
 git tag -a 1.2.0 -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
To add and push a tag attached to a commit with current time as timestamp:&lt;br /&gt;
 git tag -a 1.2.0 1bc92e2f -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
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]:&lt;br /&gt;
 # Set the HEAD to the old commit that we want to tag&lt;br /&gt;
 git checkout 9fceb02&lt;br /&gt;
 &lt;br /&gt;
 # temporarily set the date to the date of the HEAD commit, and add the tag&lt;br /&gt;
 GIT_COMMITTER_DATE=&amp;quot;$(git show --format=%aD | head -1)&amp;quot; \&lt;br /&gt;
 git tag -a v1.2 -m&amp;quot;v1.2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # push to origin&lt;br /&gt;
 git push origin --tags&lt;br /&gt;
 &lt;br /&gt;
 # set HEAD back to whatever you want it to be&lt;br /&gt;
 git checkout master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove a tag&lt;br /&gt;
|-&lt;br /&gt;
| This has a long clumsy history, but these instructions should be good into the future.&lt;br /&gt;
&lt;br /&gt;
To remove remote tag(s):&lt;br /&gt;
 git push --delete origin tag YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
Remove tag(s) locally:&lt;br /&gt;
  git tag -d YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Changing branches in a project with submodules&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 # always reset the @*$ submodules to proper commits&lt;br /&gt;
 git checkout develop &amp;amp;&amp;amp; git submodule update&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Hard-reset a misbehaving submodule to parent commit version&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git submodule deinit -f .&lt;br /&gt;
 git submodule update --init&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CONFIGURATION ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set name and email&lt;br /&gt;
|-&lt;br /&gt;
| Globally on one machine (note the machine name at end of user name):&lt;br /&gt;
 git config --global user.email m@thedigitalmachine.com;  git config user.name &amp;quot;Michael Behrns-Miller [cast]&amp;quot;&lt;br /&gt;
Override for a repository:&lt;br /&gt;
 git config user.email mbm@equityshift.io;  git config user.name &amp;quot;MBM [cast]&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default root to main not master&lt;br /&gt;
|-&lt;br /&gt;
| I love the idea of a kinder root name, suck it up alt-right down-punchers, lol.&lt;br /&gt;
Configure it to always happen:&lt;br /&gt;
 git config --global init.defaultBranch main&lt;br /&gt;
Fix it for a newly initialized repository:&lt;br /&gt;
 git branch -m main&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - ONLY PUSH CURRENT doh&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.default current&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - always create remote of a local branch name on push&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.autoSetupRemote true&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - allow push -f&lt;br /&gt;
|-&lt;br /&gt;
| When did it become necessary to configure the upstream to allow this?&lt;br /&gt;
 git config receive.denyNonFastForwards false # to allow git push -f&lt;br /&gt;
 git config receive.denyNonFastForwards true # to turn that back off, good practice i guess&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Visual difftool and mergetool setup&lt;br /&gt;
|-&lt;br /&gt;
| Meld is purdy, let&#039;s kick its tires.  Hope it actually works...&lt;br /&gt;
 git config --global diff.tool meld&lt;br /&gt;
 git config --global merge.tool meld&lt;br /&gt;
 git config --global --add difftool.prompt false&lt;br /&gt;
I used to set up kdiff3 manually, like this... (gross)&lt;br /&gt;
* LINUX - put this in ~/.gitconfig&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 &lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* WINDOZE&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* LINUX Before - What a ridiculous pita... copy this into .git/config...&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert to a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Start with a normal git repo via [git init]; add your files, get it all set up.  Then do this:&lt;br /&gt;
 cd repo&lt;br /&gt;
Now you can copy-paste this...&lt;br /&gt;
 mv .git .. &amp;amp;&amp;amp; rm -fr *&lt;br /&gt;
 mv ../.git .&lt;br /&gt;
 mv .git/* .&lt;br /&gt;
 rmdir .git&lt;br /&gt;
 git config --bool core.bare true&lt;br /&gt;
 cd ..&lt;br /&gt;
Don&#039;t copy/paste these, you need to change repo name...&lt;br /&gt;
 mv repo repo.git # rename it for clarity&lt;br /&gt;
 git clone repo.git # (optional, if you want a live repo on the server where you have the bare repo)&lt;br /&gt;
Then you can clean up old branches like daily and daily_grind, as needed.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert bare to a mirror of remote (github, facebook, etc)&lt;br /&gt;
|-&lt;br /&gt;
| You need a bare mirror repo if you want to take someone else&#039;s repo and create your own bare to work from.&lt;br /&gt;
If you did NOT specify --mirror when you first created the bare repo, you can convert to a mirror by adding these last two lines to config, underneath url:&lt;br /&gt;
 [remote &amp;quot;origin&amp;quot;]&lt;br /&gt;
    url = git@github.com:facebook/proxygen.git&lt;br /&gt;
    fetch = +refs/*:refs/*&lt;br /&gt;
    mirror = true&lt;br /&gt;
Now you can fetch from the bare repo:&lt;br /&gt;
 git fetch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create merge-to command&lt;br /&gt;
|-&lt;br /&gt;
| Add this handy alias command to all git repos&#039; .config file...&lt;br /&gt;
 [alias]&lt;br /&gt;
     merge-to = &amp;quot;!gitmergeto() { export tmp_branch=`git branch | grep &#039;* &#039; | tr -d &#039;* &#039;` &amp;amp;&amp;amp; git checkout $1 &amp;amp;&amp;amp; git merge $tmp_branch &amp;amp;&amp;amp; git checkout $tmp_branch; unset tmp_branch; }; gitmergeto&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix github diverge from local bare repo following README.md edit&lt;br /&gt;
|-&lt;br /&gt;
| Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling.&lt;br /&gt;
Fixing it is a PAIN in the ASS, you have to create a new local repo and pull github into that, pull in from your other local repo, push to github, pull to your bare... &lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git quick-http-with-readme-conflict&lt;br /&gt;
 git remote add local ../quick-http&lt;br /&gt;
 git fetch local&lt;br /&gt;
 git merge local/master # merge in changes, likely trivial&lt;br /&gt;
 git push # pushes back to github&lt;br /&gt;
 cd ..&lt;br /&gt;
 mv quick-http.git quick-http.git__gone-out-of-sync-fu-github-readme-editor&lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git --bare&lt;br /&gt;
 cp quick-http.git__gone-out-of-sync-fu-github-readme-editor/config quick-http.git/&lt;br /&gt;
And that MIGHT get you on your way... but I would no longer trust ANY of your local repos...&lt;br /&gt;
This is a serious pita.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows configure notepad++ editor&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 git config --global core.editor &amp;quot;&#039;C:/Program Files (x86)/Notepad++/notepad++.exe&#039; -multiInst -notabbar -nosession -noPlugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstreams&lt;br /&gt;
|-&lt;br /&gt;
| Use this to cause AUTOMATIC push/pull to a second origin:&lt;br /&gt;
 git remote set-url origin --push --add user1@repo1&lt;br /&gt;
 git remote set-url origin --push --add user2@repo2&lt;br /&gt;
 git remote -v show&lt;br /&gt;
Leave out --push if you want to pull as well... but I&#039;d be careful, it&#039;s better if code is changed in one client with this config, and then pushed to the multiple origins from there.  Otherwise, things are GOING TO GET SYNCY-STINKY.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Git branching strategies ===&lt;br /&gt;
==== Simplified Gitflow ====&lt;br /&gt;
This is awesome, tight, and well-capable of handling any app with a single primary release (like a website).&lt;br /&gt;
                         RELEASE TAG&lt;br /&gt;
 o----------------------------o-----------------o------------o------&amp;gt; MASTER&lt;br /&gt;
  \                          /  \                \----------/ HOTFIX&lt;br /&gt;
   \                        /    \                          \&lt;br /&gt;
    \----------------------/      \--------------------o-----o------&amp;gt; DEVELOP&lt;br /&gt;
                                   \                  /&lt;br /&gt;
                                    \----------------/ FEATURE&lt;br /&gt;
&lt;br /&gt;
Read more [https://medium.com/goodtogoat/simplified-git-flow-5dc37ba76ea8 here] and [https://gist.github.com/vxhviet/9c4a522921ad857406033c4125f343a5 here].&lt;br /&gt;
&lt;br /&gt;
==== Gitflow ====&lt;br /&gt;
I was a die-hard believer in gitflow for a while.  It&#039;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]...&lt;br /&gt;
[[File:Git for nice release planning.png]]&lt;br /&gt;
&lt;br /&gt;
=== LFS ===&lt;br /&gt;
Just don&#039;t use it.  It&#039;s shite.  If you get stuck working with a repo that requires it, and you are using ssh on linux which just won&#039;t work with LFS... you will probably end up with a damaged repo.  Fix it with this:&lt;br /&gt;
 git read-tree HEAD &amp;amp;&amp;amp; GIT_LFS_SKIP_SMUDGE=1 git checkout -f HEAD&lt;br /&gt;
After that, use &#039;&#039;&#039;GIT_LFS_SKIP_SMUDGE=1&#039;&#039;&#039; during any git command:&lt;br /&gt;
 GIT_LFS_SKIP_SMUDGE=1 git pull # etc.&lt;br /&gt;
&lt;br /&gt;
=== My git pages (older) ===&lt;br /&gt;
[[Track your changes to an open-source project with git]]&lt;br /&gt;
&lt;br /&gt;
[[Using git on Windows]]&lt;br /&gt;
&lt;br /&gt;
[[Portable git]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Microsoft_Copilot&amp;diff=7927</id>
		<title>Microsoft Copilot</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Microsoft_Copilot&amp;diff=7927"/>
		<updated>2026-01-07T00:59:49Z</updated>

		<summary type="html">&lt;p&gt;M: Created page with &amp;quot;I had [https://github.com/settings/billing subscribed to copilot] for ABT in 2025 at $10/mo.  Worked well.  Best-in-class vscode integration.  But claude code has the flow and skills now.  I unsubscribed in Jan 2026.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I had [https://github.com/settings/billing subscribed to copilot] for ABT in 2025 at $10/mo.&lt;br /&gt;
&lt;br /&gt;
Worked well.  Best-in-class vscode integration.  But claude code has the flow and skills now.  I unsubscribed in Jan 2026.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Freman&amp;diff=7926</id>
		<title>Freman</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Freman&amp;diff=7926"/>
		<updated>2026-01-06T18:12:08Z</updated>

		<summary type="html">&lt;p&gt;M: /* Network drives (Samba) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freman is a 2024 Mac Mini in the server rack.&lt;br /&gt;
&lt;br /&gt;
There are a few ways to access and do dev on it:&lt;br /&gt;
* Directly via KVM+Sony input switch; pro: this is the native acceleration and feel; con: well, it&#039;s a Mac&lt;br /&gt;
* Headless via VNC, specifically using [[Remmina]] on [[cast]; pro: just switch to workspace 6; con: slower&lt;br /&gt;
* Code on cast, push code and build and etc. via terminal; pro: awesome comfort; con: WIP&lt;br /&gt;
&lt;br /&gt;
I bought it in 2025/10 but Apple idiots say this 2024 is their &amp;quot;current release&amp;quot; (for over a year now), and even sales doesn&#039;t know when next Mini will drop.  I hate Apple.&lt;br /&gt;
&lt;br /&gt;
== Development configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Install software ===&lt;br /&gt;
* Install Xcode from the Apple Store&lt;br /&gt;
* Install [developer.apple.com/sf-symbols/|SF Symbols]&lt;br /&gt;
* Install [https://brew.sh/ homebrew] AFTER Xcode (it will then include Xcode stuff)&lt;br /&gt;
* Install ne&lt;br /&gt;
 brew install ne&lt;br /&gt;
 ne .zshrc # and set EDITOR=ne, so meta&lt;br /&gt;
* Install wget, git, meld&lt;br /&gt;
 brew install wget git meld&lt;br /&gt;
* Install nvm, npm, node&lt;br /&gt;
NOTE: again, must be done AFTER you install Xcode, but also after you create .zshrc.  Do NOT use homebrew, nvm github page says it is not supported.  Go to the github repo and run the script line from there in a terminal.&lt;br /&gt;
 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash&lt;br /&gt;
 # close and reopen terminal&lt;br /&gt;
 nvm install --lts&lt;br /&gt;
* (not sure i want this yet, it is Intel-based and requires this &amp;quot;Rosetta&amp;quot; bridge bullshit...) Pay $3 and install IconKit, saves hours of work to build stupid icon packs&lt;br /&gt;
* (not really using this yet...) Install TextMate: [https://macromates.com|download], open archive, drag app to Utilities, run, pin to dock (, add to path?)&lt;br /&gt;
&lt;br /&gt;
=== Dev env ===&lt;br /&gt;
* Set up repos&lt;br /&gt;
 cd&lt;br /&gt;
 mkdir development&lt;br /&gt;
 cd development&lt;br /&gt;
 git clone morosoph:development/scripts.git&lt;br /&gt;
 cd scripts/node/mah-haus&lt;br /&gt;
 npm install -g&lt;br /&gt;
 npm install -g @moodboom/git-semver&lt;br /&gt;
 cd ~/development&lt;br /&gt;
 mkdir -p thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 cd thedigitalage/AbetterTrader&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/server.git&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/scripts.git&lt;br /&gt;
 cd scripts/node/atci&lt;br /&gt;
 npm install -g&lt;br /&gt;
 cd ~/development/thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader.git&lt;br /&gt;
&lt;br /&gt;
* Open in Xcode: ~/development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader&lt;br /&gt;
&lt;br /&gt;
== Configure macOS ==&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
* Finder&lt;br /&gt;
 rclick in whitespace &amp;gt; Show View Options &amp;gt;&lt;br /&gt;
 [x] Always open in list view, sorted by name, hit Use as Defaults&lt;br /&gt;
&lt;br /&gt;
=== Mouse ===&lt;br /&gt;
==== Scrolling speed ====&lt;br /&gt;
Scrolling is super slow over Remmina, I found a fix [https://github.com/TigerVNC/tigervnc/issues/1741#issuecomment-2628649266 here].&lt;br /&gt;
&lt;br /&gt;
The app is called &amp;quot;mos&amp;quot;:&lt;br /&gt;
 brew install mos &lt;br /&gt;
 xattr -d com.apple.quarantine /Applications/Mos.app&lt;br /&gt;
 open /Applications/Mos.app&lt;br /&gt;
&lt;br /&gt;
BUT you have to run it every time you log in.  AND it forces natural scrolling.  I need a better fix.  FREMAN IS ICE COLD SLOW.&lt;br /&gt;
&lt;br /&gt;
==== Disable horrific natural scrolling ====&lt;br /&gt;
Apple BORG now forces natural scrolling with no UI toggle.  Hack it off with this:&lt;br /&gt;
 defaults write -g com.apple.swipescrolldirection -bool NO&lt;br /&gt;
 # log out/in&lt;br /&gt;
&lt;br /&gt;
=== Keyboard ===&lt;br /&gt;
* Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements] key mapping tool, oh yeah&lt;br /&gt;
* Run the install link in the Installation instructions at [https://github.com/rux616/karabiner-windows-mode this windows-mode repo] to get all the editor keys we NEED&lt;br /&gt;
** Older: Click predefined rules by community, search for &#039;&#039;&#039;&#039;PC-Style Shortcuts&#039;&#039;&#039;&#039; pack, wowza&lt;br /&gt;
(ok that didn&#039;t handle Ctrl-Insert (copy))&lt;br /&gt;
* Go through all the macOS permissions loosening to allow it access - you will NOT REGRET IT&lt;br /&gt;
* I could NOT find Ctrl-Ins that worked, even tho karabiner-windows-mode has TWO (they say you can&#039;t enable more than one but i tried them each separately).&lt;br /&gt;
* So, edit the file at ~/.config/karabiner/karabiner.json (Windows-Shift-. to show hidden files)&lt;br /&gt;
* You can find the karabiner-windows-mode overrides by searching for&lt;br /&gt;
 &amp;quot;key_code&amp;quot;:&amp;quot;insert&amp;quot;,&lt;br /&gt;
* Strip the conditions from it, and it will start to work!&lt;br /&gt;
&lt;br /&gt;
== Initial configuration ==&lt;br /&gt;
&lt;br /&gt;
* Plug it in&lt;br /&gt;
* WAIT&lt;br /&gt;
* Use connectors to get a mouse and kb connected to its USB-C ports; some mice/kb don&#039;t work but the Logitech/i-rocks ones do; WAIT for it to recognize them&lt;br /&gt;
* Upgrade to Tahoe&lt;br /&gt;
* Set the hostname via Apple &amp;gt; System Settings &amp;gt; Sharing (two places)&lt;br /&gt;
* Get MAC address from Apple &amp;gt; System Settings &amp;gt; Networking and update dnsmasq to give out a static IP; renew lease on mac&lt;br /&gt;
* Set display resolution to 4k (3840x2160): System Settings &amp;gt; Displays&lt;br /&gt;
&lt;br /&gt;
=== SSH ===&lt;br /&gt;
* Allow SSH: Apple &amp;gt; System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; check Remote Login&lt;br /&gt;
* [[Linux_barebones_quickstart#Copy_ssh_keys|Copy ssh keys]]&lt;br /&gt;
* Connect via ssh with kitty to teach Mac zfs terminal:&lt;br /&gt;
 m@cas[] kitty +kitten ssh freman&lt;br /&gt;
* Update /etc/ssh/sshd_config to disallow passwords, and restart sshd:&lt;br /&gt;
 sudo launchctl stop com.openssh.sshd&lt;br /&gt;
 sudo launchctl start com.openssh.sshd&lt;br /&gt;
* set aliases and a banner in ~/.zshrc&lt;br /&gt;
&lt;br /&gt;
=== Network drives (Samba) ===&lt;br /&gt;
* create this file&lt;br /&gt;
 /etc/fstab.local&lt;br /&gt;
* add a line for each share, in this format:&lt;br /&gt;
 //username:password@MACHINENAME/SHARENAME /SomeLocalFolderOfChoice smbfs 0 0&lt;br /&gt;
&lt;br /&gt;
OR...&lt;br /&gt;
* In Finder, press Command-K&lt;br /&gt;
* Provide samba string and connect, eg:&lt;br /&gt;
 smb://hive/safe&lt;br /&gt;
&lt;br /&gt;
=== Remote screen control ===&lt;br /&gt;
* Allow VNC: System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; click Remote Management (i) &amp;gt; VNC users may control ON&lt;br /&gt;
* Turn off Lock Screen: Apple &amp;gt; System Settings &amp;gt; Privacy&amp;amp;Sec &amp;gt; Lock Screen &amp;gt; Turn display off NEVER, Require after off NEVER&lt;br /&gt;
* Ensure you can start a VNC session from cast using [[Remmina]]; note the full-screen toggle is RIGHT-CONTROL-F&lt;br /&gt;
** TODO mouse scrolls in very tiny increments; I can&#039;t seem to find any solutions yet; may need to try a different VNC client&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Freman&amp;diff=7925</id>
		<title>Freman</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Freman&amp;diff=7925"/>
		<updated>2026-01-06T17:50:32Z</updated>

		<summary type="html">&lt;p&gt;M: /* Network drives (Samba) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freman is a 2024 Mac Mini in the server rack.&lt;br /&gt;
&lt;br /&gt;
There are a few ways to access and do dev on it:&lt;br /&gt;
* Directly via KVM+Sony input switch; pro: this is the native acceleration and feel; con: well, it&#039;s a Mac&lt;br /&gt;
* Headless via VNC, specifically using [[Remmina]] on [[cast]; pro: just switch to workspace 6; con: slower&lt;br /&gt;
* Code on cast, push code and build and etc. via terminal; pro: awesome comfort; con: WIP&lt;br /&gt;
&lt;br /&gt;
I bought it in 2025/10 but Apple idiots say this 2024 is their &amp;quot;current release&amp;quot; (for over a year now), and even sales doesn&#039;t know when next Mini will drop.  I hate Apple.&lt;br /&gt;
&lt;br /&gt;
== Development configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Install software ===&lt;br /&gt;
* Install Xcode from the Apple Store&lt;br /&gt;
* Install [developer.apple.com/sf-symbols/|SF Symbols]&lt;br /&gt;
* Install [https://brew.sh/ homebrew] AFTER Xcode (it will then include Xcode stuff)&lt;br /&gt;
* Install ne&lt;br /&gt;
 brew install ne&lt;br /&gt;
 ne .zshrc # and set EDITOR=ne, so meta&lt;br /&gt;
* Install wget, git, meld&lt;br /&gt;
 brew install wget git meld&lt;br /&gt;
* Install nvm, npm, node&lt;br /&gt;
NOTE: again, must be done AFTER you install Xcode, but also after you create .zshrc.  Do NOT use homebrew, nvm github page says it is not supported.  Go to the github repo and run the script line from there in a terminal.&lt;br /&gt;
 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash&lt;br /&gt;
 # close and reopen terminal&lt;br /&gt;
 nvm install --lts&lt;br /&gt;
* (not sure i want this yet, it is Intel-based and requires this &amp;quot;Rosetta&amp;quot; bridge bullshit...) Pay $3 and install IconKit, saves hours of work to build stupid icon packs&lt;br /&gt;
* (not really using this yet...) Install TextMate: [https://macromates.com|download], open archive, drag app to Utilities, run, pin to dock (, add to path?)&lt;br /&gt;
&lt;br /&gt;
=== Dev env ===&lt;br /&gt;
* Set up repos&lt;br /&gt;
 cd&lt;br /&gt;
 mkdir development&lt;br /&gt;
 cd development&lt;br /&gt;
 git clone morosoph:development/scripts.git&lt;br /&gt;
 cd scripts/node/mah-haus&lt;br /&gt;
 npm install -g&lt;br /&gt;
 npm install -g @moodboom/git-semver&lt;br /&gt;
 cd ~/development&lt;br /&gt;
 mkdir -p thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 cd thedigitalage/AbetterTrader&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/server.git&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/scripts.git&lt;br /&gt;
 cd scripts/node/atci&lt;br /&gt;
 npm install -g&lt;br /&gt;
 cd ~/development/thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader.git&lt;br /&gt;
&lt;br /&gt;
* Open in Xcode: ~/development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader&lt;br /&gt;
&lt;br /&gt;
== Configure macOS ==&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
* Finder&lt;br /&gt;
 rclick in whitespace &amp;gt; Show View Options &amp;gt;&lt;br /&gt;
 [x] Always open in list view, sorted by name, hit Use as Defaults&lt;br /&gt;
&lt;br /&gt;
=== Mouse ===&lt;br /&gt;
==== Scrolling speed ====&lt;br /&gt;
Scrolling is super slow over Remmina, I found a fix [https://github.com/TigerVNC/tigervnc/issues/1741#issuecomment-2628649266 here].&lt;br /&gt;
&lt;br /&gt;
The app is called &amp;quot;mos&amp;quot;:&lt;br /&gt;
 brew install mos &lt;br /&gt;
 xattr -d com.apple.quarantine /Applications/Mos.app&lt;br /&gt;
 open /Applications/Mos.app&lt;br /&gt;
&lt;br /&gt;
BUT you have to run it every time you log in.  AND it forces natural scrolling.  I need a better fix.  FREMAN IS ICE COLD SLOW.&lt;br /&gt;
&lt;br /&gt;
==== Disable horrific natural scrolling ====&lt;br /&gt;
Apple BORG now forces natural scrolling with no UI toggle.  Hack it off with this:&lt;br /&gt;
 defaults write -g com.apple.swipescrolldirection -bool NO&lt;br /&gt;
 # log out/in&lt;br /&gt;
&lt;br /&gt;
=== Keyboard ===&lt;br /&gt;
* Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements] key mapping tool, oh yeah&lt;br /&gt;
* Run the install link in the Installation instructions at [https://github.com/rux616/karabiner-windows-mode this windows-mode repo] to get all the editor keys we NEED&lt;br /&gt;
** Older: Click predefined rules by community, search for &#039;&#039;&#039;&#039;PC-Style Shortcuts&#039;&#039;&#039;&#039; pack, wowza&lt;br /&gt;
(ok that didn&#039;t handle Ctrl-Insert (copy))&lt;br /&gt;
* Go through all the macOS permissions loosening to allow it access - you will NOT REGRET IT&lt;br /&gt;
* I could NOT find Ctrl-Ins that worked, even tho karabiner-windows-mode has TWO (they say you can&#039;t enable more than one but i tried them each separately).&lt;br /&gt;
* So, edit the file at ~/.config/karabiner/karabiner.json (Windows-Shift-. to show hidden files)&lt;br /&gt;
* You can find the karabiner-windows-mode overrides by searching for&lt;br /&gt;
 &amp;quot;key_code&amp;quot;:&amp;quot;insert&amp;quot;,&lt;br /&gt;
* Strip the conditions from it, and it will start to work!&lt;br /&gt;
&lt;br /&gt;
== Initial configuration ==&lt;br /&gt;
&lt;br /&gt;
* Plug it in&lt;br /&gt;
* WAIT&lt;br /&gt;
* Use connectors to get a mouse and kb connected to its USB-C ports; some mice/kb don&#039;t work but the Logitech/i-rocks ones do; WAIT for it to recognize them&lt;br /&gt;
* Upgrade to Tahoe&lt;br /&gt;
* Set the hostname via Apple &amp;gt; System Settings &amp;gt; Sharing (two places)&lt;br /&gt;
* Get MAC address from Apple &amp;gt; System Settings &amp;gt; Networking and update dnsmasq to give out a static IP; renew lease on mac&lt;br /&gt;
* Set display resolution to 4k (3840x2160): System Settings &amp;gt; Displays&lt;br /&gt;
&lt;br /&gt;
=== SSH ===&lt;br /&gt;
* Allow SSH: Apple &amp;gt; System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; check Remote Login&lt;br /&gt;
* [[Linux_barebones_quickstart#Copy_ssh_keys|Copy ssh keys]]&lt;br /&gt;
* Connect via ssh with kitty to teach Mac zfs terminal:&lt;br /&gt;
 m@cas[] kitty +kitten ssh freman&lt;br /&gt;
* Update /etc/ssh/sshd_config to disallow passwords, and restart sshd:&lt;br /&gt;
 sudo launchctl stop com.openssh.sshd&lt;br /&gt;
 sudo launchctl start com.openssh.sshd&lt;br /&gt;
* set aliases and a banner in ~/.zshrc&lt;br /&gt;
&lt;br /&gt;
=== Network drives (Samba) ===&lt;br /&gt;
* create this file&lt;br /&gt;
 /etc/fstab.local&lt;br /&gt;
* add a line for each share, in this format:&lt;br /&gt;
 //username:password@MACHINENAME/SHARENAME /SomeLocalFolderOfChoice smbfs 0 0&lt;br /&gt;
&lt;br /&gt;
=== Remote screen control ===&lt;br /&gt;
* Allow VNC: System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; click Remote Management (i) &amp;gt; VNC users may control ON&lt;br /&gt;
* Turn off Lock Screen: Apple &amp;gt; System Settings &amp;gt; Privacy&amp;amp;Sec &amp;gt; Lock Screen &amp;gt; Turn display off NEVER, Require after off NEVER&lt;br /&gt;
* Ensure you can start a VNC session from cast using [[Remmina]]; note the full-screen toggle is RIGHT-CONTROL-F&lt;br /&gt;
** TODO mouse scrolls in very tiny increments; I can&#039;t seem to find any solutions yet; may need to try a different VNC client&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Freman&amp;diff=7924</id>
		<title>Freman</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Freman&amp;diff=7924"/>
		<updated>2026-01-06T17:40:02Z</updated>

		<summary type="html">&lt;p&gt;M: /* Initial configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freman is a 2024 Mac Mini in the server rack.&lt;br /&gt;
&lt;br /&gt;
There are a few ways to access and do dev on it:&lt;br /&gt;
* Directly via KVM+Sony input switch; pro: this is the native acceleration and feel; con: well, it&#039;s a Mac&lt;br /&gt;
* Headless via VNC, specifically using [[Remmina]] on [[cast]; pro: just switch to workspace 6; con: slower&lt;br /&gt;
* Code on cast, push code and build and etc. via terminal; pro: awesome comfort; con: WIP&lt;br /&gt;
&lt;br /&gt;
I bought it in 2025/10 but Apple idiots say this 2024 is their &amp;quot;current release&amp;quot; (for over a year now), and even sales doesn&#039;t know when next Mini will drop.  I hate Apple.&lt;br /&gt;
&lt;br /&gt;
== Development configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Install software ===&lt;br /&gt;
* Install Xcode from the Apple Store&lt;br /&gt;
* Install [developer.apple.com/sf-symbols/|SF Symbols]&lt;br /&gt;
* Install [https://brew.sh/ homebrew] AFTER Xcode (it will then include Xcode stuff)&lt;br /&gt;
* Install ne&lt;br /&gt;
 brew install ne&lt;br /&gt;
 ne .zshrc # and set EDITOR=ne, so meta&lt;br /&gt;
* Install wget, git, meld&lt;br /&gt;
 brew install wget git meld&lt;br /&gt;
* Install nvm, npm, node&lt;br /&gt;
NOTE: again, must be done AFTER you install Xcode, but also after you create .zshrc.  Do NOT use homebrew, nvm github page says it is not supported.  Go to the github repo and run the script line from there in a terminal.&lt;br /&gt;
 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash&lt;br /&gt;
 # close and reopen terminal&lt;br /&gt;
 nvm install --lts&lt;br /&gt;
* (not sure i want this yet, it is Intel-based and requires this &amp;quot;Rosetta&amp;quot; bridge bullshit...) Pay $3 and install IconKit, saves hours of work to build stupid icon packs&lt;br /&gt;
* (not really using this yet...) Install TextMate: [https://macromates.com|download], open archive, drag app to Utilities, run, pin to dock (, add to path?)&lt;br /&gt;
&lt;br /&gt;
=== Dev env ===&lt;br /&gt;
* Set up repos&lt;br /&gt;
 cd&lt;br /&gt;
 mkdir development&lt;br /&gt;
 cd development&lt;br /&gt;
 git clone morosoph:development/scripts.git&lt;br /&gt;
 cd scripts/node/mah-haus&lt;br /&gt;
 npm install -g&lt;br /&gt;
 npm install -g @moodboom/git-semver&lt;br /&gt;
 cd ~/development&lt;br /&gt;
 mkdir -p thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 cd thedigitalage/AbetterTrader&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/server.git&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/scripts.git&lt;br /&gt;
 cd scripts/node/atci&lt;br /&gt;
 npm install -g&lt;br /&gt;
 cd ~/development/thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader.git&lt;br /&gt;
&lt;br /&gt;
* Open in Xcode: ~/development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader&lt;br /&gt;
&lt;br /&gt;
== Configure macOS ==&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
* Finder&lt;br /&gt;
 rclick in whitespace &amp;gt; Show View Options &amp;gt;&lt;br /&gt;
 [x] Always open in list view, sorted by name, hit Use as Defaults&lt;br /&gt;
&lt;br /&gt;
=== Mouse ===&lt;br /&gt;
==== Scrolling speed ====&lt;br /&gt;
Scrolling is super slow over Remmina, I found a fix [https://github.com/TigerVNC/tigervnc/issues/1741#issuecomment-2628649266 here].&lt;br /&gt;
&lt;br /&gt;
The app is called &amp;quot;mos&amp;quot;:&lt;br /&gt;
 brew install mos &lt;br /&gt;
 xattr -d com.apple.quarantine /Applications/Mos.app&lt;br /&gt;
 open /Applications/Mos.app&lt;br /&gt;
&lt;br /&gt;
BUT you have to run it every time you log in.  AND it forces natural scrolling.  I need a better fix.  FREMAN IS ICE COLD SLOW.&lt;br /&gt;
&lt;br /&gt;
==== Disable horrific natural scrolling ====&lt;br /&gt;
Apple BORG now forces natural scrolling with no UI toggle.  Hack it off with this:&lt;br /&gt;
 defaults write -g com.apple.swipescrolldirection -bool NO&lt;br /&gt;
 # log out/in&lt;br /&gt;
&lt;br /&gt;
=== Keyboard ===&lt;br /&gt;
* Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements] key mapping tool, oh yeah&lt;br /&gt;
* Run the install link in the Installation instructions at [https://github.com/rux616/karabiner-windows-mode this windows-mode repo] to get all the editor keys we NEED&lt;br /&gt;
** Older: Click predefined rules by community, search for &#039;&#039;&#039;&#039;PC-Style Shortcuts&#039;&#039;&#039;&#039; pack, wowza&lt;br /&gt;
(ok that didn&#039;t handle Ctrl-Insert (copy))&lt;br /&gt;
* Go through all the macOS permissions loosening to allow it access - you will NOT REGRET IT&lt;br /&gt;
* I could NOT find Ctrl-Ins that worked, even tho karabiner-windows-mode has TWO (they say you can&#039;t enable more than one but i tried them each separately).&lt;br /&gt;
* So, edit the file at ~/.config/karabiner/karabiner.json (Windows-Shift-. to show hidden files)&lt;br /&gt;
* You can find the karabiner-windows-mode overrides by searching for&lt;br /&gt;
 &amp;quot;key_code&amp;quot;:&amp;quot;insert&amp;quot;,&lt;br /&gt;
* Strip the conditions from it, and it will start to work!&lt;br /&gt;
&lt;br /&gt;
== Initial configuration ==&lt;br /&gt;
&lt;br /&gt;
* Plug it in&lt;br /&gt;
* WAIT&lt;br /&gt;
* Use connectors to get a mouse and kb connected to its USB-C ports; some mice/kb don&#039;t work but the Logitech/i-rocks ones do; WAIT for it to recognize them&lt;br /&gt;
* Upgrade to Tahoe&lt;br /&gt;
* Set the hostname via Apple &amp;gt; System Settings &amp;gt; Sharing (two places)&lt;br /&gt;
* Get MAC address from Apple &amp;gt; System Settings &amp;gt; Networking and update dnsmasq to give out a static IP; renew lease on mac&lt;br /&gt;
* Set display resolution to 4k (3840x2160): System Settings &amp;gt; Displays&lt;br /&gt;
&lt;br /&gt;
=== SSH ===&lt;br /&gt;
* Allow SSH: Apple &amp;gt; System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; check Remote Login&lt;br /&gt;
* [[Linux_barebones_quickstart#Copy_ssh_keys|Copy ssh keys]]&lt;br /&gt;
* Connect via ssh with kitty to teach Mac zfs terminal:&lt;br /&gt;
 m@cas[] kitty +kitten ssh freman&lt;br /&gt;
* Update /etc/ssh/sshd_config to disallow passwords, and restart sshd:&lt;br /&gt;
 sudo launchctl stop com.openssh.sshd&lt;br /&gt;
 sudo launchctl start com.openssh.sshd&lt;br /&gt;
* set aliases and a banner in ~/.zshrc&lt;br /&gt;
&lt;br /&gt;
=== Network drives (Samba) ===&lt;br /&gt;
* create this file&lt;br /&gt;
 /etc/fstab.local&lt;br /&gt;
* add a line for each share, in this format:&lt;br /&gt;
 //username:password@MACHINENAME/SHARENAME /SomeLocalFolderOfChoice smbfs 0 0   &lt;br /&gt;
&lt;br /&gt;
=== Remote screen control ===&lt;br /&gt;
* Allow VNC: System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; click Remote Management (i) &amp;gt; VNC users may control ON&lt;br /&gt;
* Turn off Lock Screen: Apple &amp;gt; System Settings &amp;gt; Privacy&amp;amp;Sec &amp;gt; Lock Screen &amp;gt; Turn display off NEVER, Require after off NEVER&lt;br /&gt;
* Ensure you can start a VNC session from cast using [[Remmina]]; note the full-screen toggle is RIGHT-CONTROL-F&lt;br /&gt;
** TODO mouse scrolls in very tiny increments; I can&#039;t seem to find any solutions yet; may need to try a different VNC client&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Git&amp;diff=7923</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Git&amp;diff=7923"/>
		<updated>2026-01-05T20:43:41Z</updated>

		<summary type="html">&lt;p&gt;M: /* TASKS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== TASKS ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set up a new shitcutter project&lt;br /&gt;
|-&lt;br /&gt;
| This is my development setup:&lt;br /&gt;
 gitlab-repo &amp;lt; shared-bare-repo &amp;lt; lan-clients&lt;br /&gt;
&lt;br /&gt;
My shared-bare-repos are my source of truth.  I don&#039;t want it to be gitlab, that just gets in the way when I&#039;m on my LAN.  But I do push code up there when I want to share with others.&lt;br /&gt;
&lt;br /&gt;
Setting up a new project is a bit annoying.  Make this better:&lt;br /&gt;
&lt;br /&gt;
* Create the gitlab project with repo support.  Go to Settings &amp;gt; Repository &amp;gt; Protected branches and enable &amp;quot;Allowed to force push&amp;quot;.&lt;br /&gt;
* Create a new shared bare repo on LAN.&lt;br /&gt;
* Configure the bare repo to have the gitlab repo as upstream.&lt;br /&gt;
 git remote add sc git@shitcutter.com:the-digital-age/teamtunes/teamtunes-android.git&lt;br /&gt;
 git fetch&lt;br /&gt;
* Configure the bare repo to push to upstream on receive:&lt;br /&gt;
  🤔 m@morosoph  [~/development/thedigitalage/TeamTunes/TeamTunes-android.git] cp ../TeamTunes-iOS.git/hooks/post-receive hooks/&lt;br /&gt;
* Clone shared-bare repo to a client.&lt;br /&gt;
 git clone morosoph:development/thedigitalage/TeamTunes/TeamTunes-android.git&lt;br /&gt;
* Create a main branch on the client.  SADLY YOU HAVE TO COMMIT SOMETHING.  What bs, git...&lt;br /&gt;
 git branch -M main&lt;br /&gt;
 git touch readme.txt&lt;br /&gt;
 git add readme.txt&lt;br /&gt;
 git commit -a -m &amp;quot;Init&amp;quot;&lt;br /&gt;
* Force-push the branch from client to bare repo, it should go all the way to shitcutter:&lt;br /&gt;
 git push -uf main&lt;br /&gt;
* Go back to the gitlab project &amp;gt; Settings &amp;gt; Repository &amp;gt; Protected branches and disable &amp;quot;Allowed to force push&amp;quot;.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! New shared central bare repo&lt;br /&gt;
|-&lt;br /&gt;
| On central server (aka morosoph):&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git init --bare --shared mynewthang.git&lt;br /&gt;
On development box&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git clone morosoph:development/mynewthang.git&lt;br /&gt;
 # this will create a new empty repo with no branch yet&lt;br /&gt;
 # TO CREATE MASTER BRANCH (this is the only way):&lt;br /&gt;
 # create files, git add, git commit, git push&lt;br /&gt;
Back on bitpost&lt;br /&gt;
 git clone mynewthang.git # to create a working copy on server, if desired&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! create shared central repo for existing code&lt;br /&gt;
|-&lt;br /&gt;
| Create a bare repo with .git suffix&lt;br /&gt;
 git init --bare --shared mything.git&lt;br /&gt;
Go to existing code and clone the repo next to it, with a temp name.  &lt;br /&gt;
Move .git into the existing code.&lt;br /&gt;
Add code, add a .gitignore as needed, and you&#039;re all set.&lt;br /&gt;
 cd mything/..&lt;br /&gt;
 git clone (bare-repo-host-and-path)mything.git mything-temp&lt;br /&gt;
 mv mything-temp/.git mything/&lt;br /&gt;
 rm -rf mything-temp&lt;br /&gt;
 cd mything&lt;br /&gt;
 code .gitignore # as needed&lt;br /&gt;
 git add (whatever you want to track)&lt;br /&gt;
 git commit -a -m &amp;quot;init repo&amp;quot; &amp;amp;&amp;amp; git push&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fetch a branch from remote without checking it out&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are rebasing a feature branch.&lt;br /&gt;
 git fetch origin develop:develop&lt;br /&gt;
You would think &amp;lt;code&amp;gt;git fetch --all&amp;lt;/code&amp;gt; would do it but does not (it fetches the active branch from &#039;&#039;all origins&#039;&#039; - seriously wtf, who ever wants THAT??).&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Completely reset an out-of-sync branch to 100% match the remote&lt;br /&gt;
|-&lt;br /&gt;
| 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:&lt;br /&gt;
 git reset --hard origin/thebranchname&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default branch of a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| If you want the default branch of a bare repo to be something other than master:&lt;br /&gt;
 git branch&lt;br /&gt;
  * master&lt;br /&gt;
    moodboom-quick-http&lt;br /&gt;
 git symbolic-ref HEAD refs/heads/moodboom-quick-http&lt;br /&gt;
 git branch&lt;br /&gt;
    master&lt;br /&gt;
  * moodboom-quick-http&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Get a file from another branch&lt;br /&gt;
|-&lt;br /&gt;
| Grab the latest version in otherBranch and dump it into your current branch main:&lt;br /&gt;
 git switch main&lt;br /&gt;
 git restore --source otherBranch -- myfile.js&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Find a file across branches&lt;br /&gt;
|-&lt;br /&gt;
| It&#039;s clunky, two steps, and you have to glob out the whole fucking name:&lt;br /&gt;
 # get the commits that involved the filename&lt;br /&gt;
 git log --all -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # even better, get the filenames too, and see if it was added or removed:&lt;br /&gt;
 git log --all --stat -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # now find the branch with one of those commits:&lt;br /&gt;
 git branch -a --contains #commithash#&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gitflow&lt;br /&gt;
|-&lt;br /&gt;
| Gitflow is awesome, using it myself and everywhere I work these days (2020).&lt;br /&gt;
* Devs work out of develop branch&lt;br /&gt;
* Devs create feature branches off develop for any decent-sized work&lt;br /&gt;
* Once develop is stable and you are ready for a release:&lt;br /&gt;
 git tag -a -m &amp;quot;#MAJOR#.#MINOR#&amp;quot;.0 #MAJOR#.#MINOR#.0&lt;br /&gt;
 git checkout -b release/release_#MAJOR#.#MINOR#&lt;br /&gt;
 git push --set-upstream origin release_#MAJOR#.#MINOR#&lt;br /&gt;
 git checkout master &amp;amp;&amp;amp; git merge release/release_#MAJOR#.#MINOR# &amp;amp;&amp;amp; git push&lt;br /&gt;
 git checkout develop # and get back to it!&lt;br /&gt;
* Do hotfixes as needed in release branch, tagged #MAJOR#.#MINOR#.++, merged back into master and develop&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Interactive rebase with squash&lt;br /&gt;
|-&lt;br /&gt;
| Excellent to do when on your own feature branch.  Illegal to do if branch is shared AT ALL!&lt;br /&gt;
 git rebase -i myparentbranch&lt;br /&gt;
 # work through squash and merge - gitlens may help with squash if you use vscode for EDITOR&lt;br /&gt;
 git push -f&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Push any branch from bare to origin&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are force-pushing a branch rebase.&lt;br /&gt;
 git push [-f] origin mybranch:mybranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstream config example&lt;br /&gt;
|-&lt;br /&gt;
| If you edit a file in GitLab, you may need to pull it from remote &amp;quot;gitlab&amp;quot; and push it to remote &amp;quot;sc&amp;quot;, like this:&lt;br /&gt;
 git fetch gitlab develop:develop&lt;br /&gt;
 git push sc&lt;br /&gt;
This assumes you have something like the following in your config:&lt;br /&gt;
 [remote &amp;quot;sc&amp;quot;]&lt;br /&gt;
        url = git@shitcutter.com:the-digital-age/rad-scripts.git&lt;br /&gt;
        fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;github.com&amp;quot;]&lt;br /&gt;
	url = git@github.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;gitlab.com&amp;quot;]&lt;br /&gt;
	url = git@gitlab.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merging conflicts after diverging&lt;br /&gt;
|-&lt;br /&gt;
| Revert local changes in a file to HEAD&lt;br /&gt;
 git checkout -- path/to/file.txt&lt;br /&gt;
Discard ALL LOCAL COMMITS and get the (possibly diverged) remote instead&lt;br /&gt;
 git reset --hard origin/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and push a feature branch&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
 git checkout -b feature/whiz-bang&lt;br /&gt;
 &lt;br /&gt;
 # Do this ONCE: git config --global push.default current&lt;br /&gt;
 # From then on:&lt;br /&gt;
 git push -u&lt;br /&gt;
 &lt;br /&gt;
 # OR, if you don&#039;t want the config, you have to be more specific:&lt;br /&gt;
 # git push -u origin feature/whiz-bang&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab GITFLOW fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
&lt;br /&gt;
This is very easy if you have left the master branch alone for the parent&#039;s commits, and keep your add-on commits in a release-x.x branch, as we have for SWS and SWSS.&lt;br /&gt;
&lt;br /&gt;
 cdl&lt;br /&gt;
 # Clone local repo directly from GitLab (already done on cobra)&lt;br /&gt;
 git clone git@gitlab.com:moodboom/Simple-Web-Server.git SWS-gitlab-moodboom&lt;br /&gt;
 cd SWS-gitlab-moodboom&lt;br /&gt;
 # make sure master is checked out&lt;br /&gt;
 git branch&lt;br /&gt;
 # add parent as remote&lt;br /&gt;
 git remote add ole-upstream git@gitlab.com:eidheim/Simple-Web-Server.git&lt;br /&gt;
 git fetch ole-upstream&lt;br /&gt;
 git rebase ole-upstream/master&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
You can now delete the fresh clone, it has done its job.  Or leave it for ease-of-use for next rebase.&lt;br /&gt;
&lt;br /&gt;
Now update your bare repo on bitpost, to keep things in sync.&lt;br /&gt;
 git fetch origin master:master -f&lt;br /&gt;
&lt;br /&gt;
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&#039;s what you want)  It is the gitflow way!&lt;br /&gt;
&lt;br /&gt;
Push your new branch to bare, then push bare to GitLab via something like:&lt;br /&gt;
 git push --set-upstream origin release/abt-0.0.3&lt;br /&gt;
&lt;br /&gt;
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!)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://gitlab.com/someauthor/theprojectiforked&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
If you haven&#039;t done so, in GitLab, go to [https://gitlab.com/moodboom/Simple-WebSocket-Server/-/settings/repository#js-protected-branches-settings the &amp;quot;Protected Branch&amp;quot; settings] and remove protection from master - it&#039;s just a fact that you&#039;re going to need to force-push to master.&lt;br /&gt;
&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitLab. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
You will want to force-fetch to update the bare repo you may have on bitpost, DO THIS NOW or you will screw things up badly later:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git fetch origin master:master -f&lt;br /&gt;
You should also force-update ALL your dev repos, NOW, for the same reason:&lt;br /&gt;
 git reset --hard HEAD^^^^^^ &amp;amp;&amp;amp; git pull&lt;br /&gt;
NOTE that you may need to remove a remote-tracking branch if you don&#039;t need it any more.  It&#039;s stupidly painful to get right, eg:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git branch -rd eidheim/Simple-WebSocket-Server/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitHub fork&lt;br /&gt;
|-&lt;br /&gt;
| From [http://stackoverflow.com/a/7244456/717274 so...]&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://github.com/someauthor/theprojectiforked.git&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitHub. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
Now master has the latest commits from the fork origin.  You can rebase onto it, if you&#039;ve been working in a branch (good):&lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git rebase master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Clone a bare repo (eg github, gitlab, bb) into a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Say you want a bare repo to be shared by all your dev environments, but you need to push/pull THAT from a central bare repo, too.&lt;br /&gt;
 git clone --bare --shared git@bitbucket.org:equityshift/es-demo.git&lt;br /&gt;
 cd es-demo.git&lt;br /&gt;
 git config remote.origin.fetch &amp;quot;+*:*&amp;quot;&lt;br /&gt;
 git fetch --all&lt;br /&gt;
I was surprised that this was difficult at all, and may still have some lessons to learn...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch on server, pull to client&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 # ON CENTRAL SERVER&lt;br /&gt;
 git checkout master # as needed; we are assuming that master is clean enough as a starting point&lt;br /&gt;
 git checkout -b mynewbranchy&lt;br /&gt;
 &lt;br /&gt;
 # HOWEVER, use this instead if you need a new &amp;quot;clean&amp;quot; repo and even master is dirty...&lt;br /&gt;
 # You need the rm because git &amp;quot;leaves your working folder intact&amp;quot;.&lt;br /&gt;
 git checkout --orphan mynewbranchy&lt;br /&gt;
 git rm -rf .&lt;br /&gt;
 &lt;br /&gt;
 # ON CLIENT&lt;br /&gt;
 git pull&lt;br /&gt;
 git checkout -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
 # if files are in the way from the previously checked-out branch, you can force it...&lt;br /&gt;
 git checkout -f -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merge changes in a single file&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/11593308/717274 here].  &lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git checkout --patch develop my/single/file.cpp&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove old branches&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/23961231/717274 here].  &lt;br /&gt;
Remote:&lt;br /&gt;
 git push origin --delete &amp;lt;branch&amp;gt;&lt;br /&gt;
Local:&lt;br /&gt;
 git branch -d &amp;lt;branch&amp;gt;&lt;br /&gt;
 git fetch &amp;lt;remote&amp;gt; --prune # Delete multiple obsolete tracking branches&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Work with two local repos&lt;br /&gt;
|-&lt;br /&gt;
| Set up a remote, then fetch it as master.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout --track otherplace/master # or other branch as needed; this creates the branch and sets remote in one step, cool&lt;br /&gt;
Set up a remote, then fetch it into a non-master branch, and push it to the active origin.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout otherplace/master # creates it detached, good because we need to name the new branch something other than master&lt;br /&gt;
 git checkout -b new_otherplace_branchname # creates new local branch with a good name&lt;br /&gt;
 git push --set-upstream origin new_otherplace_branchname # takes the branch from the OLD origin and pushes it to the ACTIVE origin, cool!&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Pull when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
| This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo:&lt;br /&gt;
 git fetch --all&lt;br /&gt;
 git reset --hard origin/mymatchingbranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
   git checkout -b bj143 origin/bj143&lt;br /&gt;
      git : error: The following untracked working tree files would be overwritten by checkout:&lt;br /&gt;
      (etc)&lt;br /&gt;
   &lt;br /&gt;
   TOTAL PURGE FIX (too much):&lt;br /&gt;
      git clean  -d  -fn &amp;quot;&amp;quot;&lt;br /&gt;
         -d dirs too&lt;br /&gt;
         -f force, required&lt;br /&gt;
         -x include ignored files (don&#039;t use this)&lt;br /&gt;
         -n dry run&lt;br /&gt;
   &lt;br /&gt;
   BEST FIX (just overwrite what is in the way):&lt;br /&gt;
      git checkout -f -b bj143 origin/bj143&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Recreate repo&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git clone ssh://m@thedigitalmachine.com/home/m/development/thedigitalage/ampache-with-hangthedj-module&lt;br /&gt;
 cd ampache-with-hangthedj-module&lt;br /&gt;
 git checkout -b daily_grind origin/daily_grind&lt;br /&gt;
If you already have the daily_grind branches and just need to connect them:&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Connect to origin after the fact&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git remote add origin ssh:// m@bitpost.com/home/m/development/logs&lt;br /&gt;
 git fetch&lt;br /&gt;
     From ssh:// bitpost/home/m/development/logs&lt;br /&gt;
      * [new branch]      daily_grind -&amp;gt; origin/daily_grind&lt;br /&gt;
      * [new branch]      master     -&amp;gt; origin/master&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git branch -u origin/master master&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ignore local and remote changes to a file &lt;br /&gt;
|-&lt;br /&gt;
| This is helpful for conf files that need local-specific modifications that shouldn&#039;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].&lt;br /&gt;
&lt;br /&gt;
        PREVENT COMMIT OF CHANGES TO A LOCAL FILE&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
        git update-index --skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        RESET TO GET CHANGES AGAIN&lt;br /&gt;
        --------------------------&lt;br /&gt;
        git update-index --no-skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        LIST SKIPPED FILES&lt;br /&gt;
        ------------------&lt;br /&gt;
        git ls-files -v . | grep ^S&lt;br /&gt;
        S app/views/_partials/jsIncludes.scala.html&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Replace name and email of last commit&lt;br /&gt;
|-&lt;br /&gt;
| Reset the name and email of the last commit, when you realize you forgot to set them first:&lt;br /&gt;
 git commit --amend --author=&amp;quot;First Last &amp;lt;email&amp;gt;&amp;quot; --no-edit&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Simple tagging (when not using git-sync)&lt;br /&gt;
|-&lt;br /&gt;
| To add and push a tag to HEAD:&lt;br /&gt;
 git tag -a 1.2.0 -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
To add and push a tag attached to a commit with current time as timestamp:&lt;br /&gt;
 git tag -a 1.2.0 1bc92e2f -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
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]:&lt;br /&gt;
 # Set the HEAD to the old commit that we want to tag&lt;br /&gt;
 git checkout 9fceb02&lt;br /&gt;
 &lt;br /&gt;
 # temporarily set the date to the date of the HEAD commit, and add the tag&lt;br /&gt;
 GIT_COMMITTER_DATE=&amp;quot;$(git show --format=%aD | head -1)&amp;quot; \&lt;br /&gt;
 git tag -a v1.2 -m&amp;quot;v1.2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # push to origin&lt;br /&gt;
 git push origin --tags&lt;br /&gt;
 &lt;br /&gt;
 # set HEAD back to whatever you want it to be&lt;br /&gt;
 git checkout master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove a tag&lt;br /&gt;
|-&lt;br /&gt;
| This has a long clumsy history, but these instructions should be good into the future.&lt;br /&gt;
&lt;br /&gt;
To remove remote tag(s):&lt;br /&gt;
 git push --delete origin tag YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
Remove tag(s) locally:&lt;br /&gt;
  git tag -d YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Changing branches in a project with submodules&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 # always reset the @*$ submodules to proper commits&lt;br /&gt;
 git checkout develop &amp;amp;&amp;amp; git submodule update&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Hard-reset a misbehaving submodule to parent commit version&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git submodule deinit -f .&lt;br /&gt;
 git submodule update --init&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CONFIGURATION ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set name and email&lt;br /&gt;
|-&lt;br /&gt;
| Globally on one machine (note the machine name at end of user name):&lt;br /&gt;
 git config --global user.email m@thedigitalmachine.com;  git config user.name &amp;quot;Michael Behrns-Miller [cast]&amp;quot;&lt;br /&gt;
Override for a repository:&lt;br /&gt;
 git config user.email mbm@equityshift.io;  git config user.name &amp;quot;MBM [cast]&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default root to main not master&lt;br /&gt;
|-&lt;br /&gt;
| I love the idea of a kinder root name, suck it up alt-right down-punchers, lol.&lt;br /&gt;
Configure it to always happen:&lt;br /&gt;
 git config --global init.defaultBranch main&lt;br /&gt;
Fix it for a newly initialized repository:&lt;br /&gt;
 git branch -m main&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - ONLY PUSH CURRENT doh&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.default current&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - always create remote of a local branch name on push&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.autoSetupRemote true&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - allow push -f&lt;br /&gt;
|-&lt;br /&gt;
| When did it become necessary to configure the upstream to allow this?&lt;br /&gt;
 git config receive.denyNonFastForwards false # to allow git push -f&lt;br /&gt;
 git config receive.denyNonFastForwards true # to turn that back off, good practice i guess&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Visual difftool and mergetool setup&lt;br /&gt;
|-&lt;br /&gt;
| Meld is purdy, let&#039;s kick its tires.  Hope it actually works...&lt;br /&gt;
 git config --global diff.tool meld&lt;br /&gt;
 git config --global merge.tool meld&lt;br /&gt;
 git config --global --add difftool.prompt false&lt;br /&gt;
I used to set up kdiff3 manually, like this... (gross)&lt;br /&gt;
* LINUX - put this in ~/.gitconfig&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 &lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* WINDOZE&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* LINUX Before - What a ridiculous pita... copy this into .git/config...&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert to a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Start with a normal git repo via [git init]; add your files, get it all set up.  Then do this:&lt;br /&gt;
 cd repo&lt;br /&gt;
Now you can copy-paste this...&lt;br /&gt;
 mv .git .. &amp;amp;&amp;amp; rm -fr *&lt;br /&gt;
 mv ../.git .&lt;br /&gt;
 mv .git/* .&lt;br /&gt;
 rmdir .git&lt;br /&gt;
 git config --bool core.bare true&lt;br /&gt;
 cd ..&lt;br /&gt;
Don&#039;t copy/paste these, you need to change repo name...&lt;br /&gt;
 mv repo repo.git # rename it for clarity&lt;br /&gt;
 git clone repo.git # (optional, if you want a live repo on the server where you have the bare repo)&lt;br /&gt;
Then you can clean up old branches like daily and daily_grind, as needed.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert bare to a mirror of remote (github, facebook, etc)&lt;br /&gt;
|-&lt;br /&gt;
| You need a bare mirror repo if you want to take someone else&#039;s repo and create your own bare to work from.&lt;br /&gt;
If you did NOT specify --mirror when you first created the bare repo, you can convert to a mirror by adding these last two lines to config, underneath url:&lt;br /&gt;
 [remote &amp;quot;origin&amp;quot;]&lt;br /&gt;
    url = git@github.com:facebook/proxygen.git&lt;br /&gt;
    fetch = +refs/*:refs/*&lt;br /&gt;
    mirror = true&lt;br /&gt;
Now you can fetch from the bare repo:&lt;br /&gt;
 git fetch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create merge-to command&lt;br /&gt;
|-&lt;br /&gt;
| Add this handy alias command to all git repos&#039; .config file...&lt;br /&gt;
 [alias]&lt;br /&gt;
     merge-to = &amp;quot;!gitmergeto() { export tmp_branch=`git branch | grep &#039;* &#039; | tr -d &#039;* &#039;` &amp;amp;&amp;amp; git checkout $1 &amp;amp;&amp;amp; git merge $tmp_branch &amp;amp;&amp;amp; git checkout $tmp_branch; unset tmp_branch; }; gitmergeto&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix github diverge from local bare repo following README.md edit&lt;br /&gt;
|-&lt;br /&gt;
| Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling.&lt;br /&gt;
Fixing it is a PAIN in the ASS, you have to create a new local repo and pull github into that, pull in from your other local repo, push to github, pull to your bare... &lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git quick-http-with-readme-conflict&lt;br /&gt;
 git remote add local ../quick-http&lt;br /&gt;
 git fetch local&lt;br /&gt;
 git merge local/master # merge in changes, likely trivial&lt;br /&gt;
 git push # pushes back to github&lt;br /&gt;
 cd ..&lt;br /&gt;
 mv quick-http.git quick-http.git__gone-out-of-sync-fu-github-readme-editor&lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git --bare&lt;br /&gt;
 cp quick-http.git__gone-out-of-sync-fu-github-readme-editor/config quick-http.git/&lt;br /&gt;
And that MIGHT get you on your way... but I would no longer trust ANY of your local repos...&lt;br /&gt;
This is a serious pita.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows configure notepad++ editor&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 git config --global core.editor &amp;quot;&#039;C:/Program Files (x86)/Notepad++/notepad++.exe&#039; -multiInst -notabbar -nosession -noPlugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstreams&lt;br /&gt;
|-&lt;br /&gt;
| Use this to cause AUTOMATIC push/pull to a second origin:&lt;br /&gt;
 git remote set-url origin --push --add user1@repo1&lt;br /&gt;
 git remote set-url origin --push --add user2@repo2&lt;br /&gt;
 git remote -v show&lt;br /&gt;
Leave out --push if you want to pull as well... but I&#039;d be careful, it&#039;s better if code is changed in one client with this config, and then pushed to the multiple origins from there.  Otherwise, things are GOING TO GET SYNCY-STINKY.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Git branching strategies ===&lt;br /&gt;
==== Simplified Gitflow ====&lt;br /&gt;
This is awesome, tight, and well-capable of handling any app with a single primary release (like a website).&lt;br /&gt;
                         RELEASE TAG&lt;br /&gt;
 o----------------------------o-----------------o------------o------&amp;gt; MASTER&lt;br /&gt;
  \                          /  \                \----------/ HOTFIX&lt;br /&gt;
   \                        /    \                          \&lt;br /&gt;
    \----------------------/      \--------------------o-----o------&amp;gt; DEVELOP&lt;br /&gt;
                                   \                  /&lt;br /&gt;
                                    \----------------/ FEATURE&lt;br /&gt;
&lt;br /&gt;
Read more [https://medium.com/goodtogoat/simplified-git-flow-5dc37ba76ea8 here] and [https://gist.github.com/vxhviet/9c4a522921ad857406033c4125f343a5 here].&lt;br /&gt;
&lt;br /&gt;
==== Gitflow ====&lt;br /&gt;
I was a die-hard believer in gitflow for a while.  It&#039;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]...&lt;br /&gt;
[[File:Git for nice release planning.png]]&lt;br /&gt;
&lt;br /&gt;
=== LFS ===&lt;br /&gt;
Just don&#039;t use it.  It&#039;s shite.  If you get stuck working with a repo that requires it, and you are using ssh on linux which just won&#039;t work with LFS... you will probably end up with a damaged repo.  Fix it with this:&lt;br /&gt;
 git read-tree HEAD &amp;amp;&amp;amp; GIT_LFS_SKIP_SMUDGE=1 git checkout -f HEAD&lt;br /&gt;
After that, use &#039;&#039;&#039;GIT_LFS_SKIP_SMUDGE=1&#039;&#039;&#039; during any git command:&lt;br /&gt;
 GIT_LFS_SKIP_SMUDGE=1 git pull # etc.&lt;br /&gt;
&lt;br /&gt;
=== My git pages (older) ===&lt;br /&gt;
[[Track your changes to an open-source project with git]]&lt;br /&gt;
&lt;br /&gt;
[[Using git on Windows]]&lt;br /&gt;
&lt;br /&gt;
[[Portable git]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Git&amp;diff=7922</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Git&amp;diff=7922"/>
		<updated>2026-01-05T20:18:02Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== TASKS ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set up a new shitcutter project&lt;br /&gt;
|-&lt;br /&gt;
| This is my development setup:&lt;br /&gt;
 gitlab-repo &amp;lt; shared-bare-repo &amp;lt; clients&lt;br /&gt;
&lt;br /&gt;
My shared-bare-repos are my source of truth.  I don&#039;t want it to be gitlab, that just gets in the way when I&#039;m on my LAN.  But I do push code up there when I want to share with others.&lt;br /&gt;
&lt;br /&gt;
To set up a new project:&lt;br /&gt;
&lt;br /&gt;
* Create the gitlab project with repo support.&lt;br /&gt;
* Create a new shared bare repo on LAN.&lt;br /&gt;
* Configure the bare repo to have the gitlab repo as upstream.&lt;br /&gt;
 git remote add sc git@shitcutter.com:the-digital-age/teamtunes/teamtunes-android.git&lt;br /&gt;
 git fetch&lt;br /&gt;
* Configure the bare repo to push to upstream on receive:&lt;br /&gt;
  🤔 m@morosoph  [~/development/thedigitalage/TeamTunes/TeamTunes-android.git] cp ../TeamTunes-iOS.git/hooks/post-receive hooks/&lt;br /&gt;
* Clone shared-bare repo to a client.&lt;br /&gt;
 git clone morosoph:development/thedigitalage/TeamTunes/TeamTunes-android.git&lt;br /&gt;
* Create a main branch on the client.&lt;br /&gt;
 git branch -M main&lt;br /&gt;
* Force-push the branch from client to bare repo:&lt;br /&gt;
 git push -uf main&lt;br /&gt;
It should go all the way to shitcutter.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! New shared central bare repo&lt;br /&gt;
|-&lt;br /&gt;
| On central server (aka morosoph):&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git init --bare --shared mynewthang.git&lt;br /&gt;
On development box&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git clone morosoph:development/mynewthang.git&lt;br /&gt;
 # this will create a new empty repo with no branch yet&lt;br /&gt;
 # TO CREATE MASTER BRANCH (this is the only way):&lt;br /&gt;
 # create files, git add, git commit, git push&lt;br /&gt;
Back on bitpost&lt;br /&gt;
 git clone mynewthang.git # to create a working copy on server, if desired&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! create shared central repo for existing code&lt;br /&gt;
|-&lt;br /&gt;
| Create a bare repo with .git suffix&lt;br /&gt;
 git init --bare --shared mything.git&lt;br /&gt;
Go to existing code and clone the repo next to it, with a temp name.  &lt;br /&gt;
Move .git into the existing code.&lt;br /&gt;
Add code, add a .gitignore as needed, and you&#039;re all set.&lt;br /&gt;
 cd mything/..&lt;br /&gt;
 git clone (bare-repo-host-and-path)mything.git mything-temp&lt;br /&gt;
 mv mything-temp/.git mything/&lt;br /&gt;
 rm -rf mything-temp&lt;br /&gt;
 cd mything&lt;br /&gt;
 code .gitignore # as needed&lt;br /&gt;
 git add (whatever you want to track)&lt;br /&gt;
 git commit -a -m &amp;quot;init repo&amp;quot; &amp;amp;&amp;amp; git push&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fetch a branch from remote without checking it out&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are rebasing a feature branch.&lt;br /&gt;
 git fetch origin develop:develop&lt;br /&gt;
You would think &amp;lt;code&amp;gt;git fetch --all&amp;lt;/code&amp;gt; would do it but does not (it fetches the active branch from &#039;&#039;all origins&#039;&#039; - seriously wtf, who ever wants THAT??).&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Completely reset an out-of-sync branch to 100% match the remote&lt;br /&gt;
|-&lt;br /&gt;
| 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:&lt;br /&gt;
 git reset --hard origin/thebranchname&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default branch of a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| If you want the default branch of a bare repo to be something other than master:&lt;br /&gt;
 git branch&lt;br /&gt;
  * master&lt;br /&gt;
    moodboom-quick-http&lt;br /&gt;
 git symbolic-ref HEAD refs/heads/moodboom-quick-http&lt;br /&gt;
 git branch&lt;br /&gt;
    master&lt;br /&gt;
  * moodboom-quick-http&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Get a file from another branch&lt;br /&gt;
|-&lt;br /&gt;
| Grab the latest version in otherBranch and dump it into your current branch main:&lt;br /&gt;
 git switch main&lt;br /&gt;
 git restore --source otherBranch -- myfile.js&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Find a file across branches&lt;br /&gt;
|-&lt;br /&gt;
| It&#039;s clunky, two steps, and you have to glob out the whole fucking name:&lt;br /&gt;
 # get the commits that involved the filename&lt;br /&gt;
 git log --all -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # even better, get the filenames too, and see if it was added or removed:&lt;br /&gt;
 git log --all --stat -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # now find the branch with one of those commits:&lt;br /&gt;
 git branch -a --contains #commithash#&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gitflow&lt;br /&gt;
|-&lt;br /&gt;
| Gitflow is awesome, using it myself and everywhere I work these days (2020).&lt;br /&gt;
* Devs work out of develop branch&lt;br /&gt;
* Devs create feature branches off develop for any decent-sized work&lt;br /&gt;
* Once develop is stable and you are ready for a release:&lt;br /&gt;
 git tag -a -m &amp;quot;#MAJOR#.#MINOR#&amp;quot;.0 #MAJOR#.#MINOR#.0&lt;br /&gt;
 git checkout -b release/release_#MAJOR#.#MINOR#&lt;br /&gt;
 git push --set-upstream origin release_#MAJOR#.#MINOR#&lt;br /&gt;
 git checkout master &amp;amp;&amp;amp; git merge release/release_#MAJOR#.#MINOR# &amp;amp;&amp;amp; git push&lt;br /&gt;
 git checkout develop # and get back to it!&lt;br /&gt;
* Do hotfixes as needed in release branch, tagged #MAJOR#.#MINOR#.++, merged back into master and develop&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Interactive rebase with squash&lt;br /&gt;
|-&lt;br /&gt;
| Excellent to do when on your own feature branch.  Illegal to do if branch is shared AT ALL!&lt;br /&gt;
 git rebase -i myparentbranch&lt;br /&gt;
 # work through squash and merge - gitlens may help with squash if you use vscode for EDITOR&lt;br /&gt;
 git push -f&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Push any branch from bare to origin&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are force-pushing a branch rebase.&lt;br /&gt;
 git push [-f] origin mybranch:mybranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstream config example&lt;br /&gt;
|-&lt;br /&gt;
| If you edit a file in GitLab, you may need to pull it from remote &amp;quot;gitlab&amp;quot; and push it to remote &amp;quot;sc&amp;quot;, like this:&lt;br /&gt;
 git fetch gitlab develop:develop&lt;br /&gt;
 git push sc&lt;br /&gt;
This assumes you have something like the following in your config:&lt;br /&gt;
 [remote &amp;quot;sc&amp;quot;]&lt;br /&gt;
        url = git@shitcutter.com:the-digital-age/rad-scripts.git&lt;br /&gt;
        fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;github.com&amp;quot;]&lt;br /&gt;
	url = git@github.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;gitlab.com&amp;quot;]&lt;br /&gt;
	url = git@gitlab.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merging conflicts after diverging&lt;br /&gt;
|-&lt;br /&gt;
| Revert local changes in a file to HEAD&lt;br /&gt;
 git checkout -- path/to/file.txt&lt;br /&gt;
Discard ALL LOCAL COMMITS and get the (possibly diverged) remote instead&lt;br /&gt;
 git reset --hard origin/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and push a feature branch&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
 git checkout -b feature/whiz-bang&lt;br /&gt;
 &lt;br /&gt;
 # Do this ONCE: git config --global push.default current&lt;br /&gt;
 # From then on:&lt;br /&gt;
 git push -u&lt;br /&gt;
 &lt;br /&gt;
 # OR, if you don&#039;t want the config, you have to be more specific:&lt;br /&gt;
 # git push -u origin feature/whiz-bang&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab GITFLOW fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
&lt;br /&gt;
This is very easy if you have left the master branch alone for the parent&#039;s commits, and keep your add-on commits in a release-x.x branch, as we have for SWS and SWSS.&lt;br /&gt;
&lt;br /&gt;
 cdl&lt;br /&gt;
 # Clone local repo directly from GitLab (already done on cobra)&lt;br /&gt;
 git clone git@gitlab.com:moodboom/Simple-Web-Server.git SWS-gitlab-moodboom&lt;br /&gt;
 cd SWS-gitlab-moodboom&lt;br /&gt;
 # make sure master is checked out&lt;br /&gt;
 git branch&lt;br /&gt;
 # add parent as remote&lt;br /&gt;
 git remote add ole-upstream git@gitlab.com:eidheim/Simple-Web-Server.git&lt;br /&gt;
 git fetch ole-upstream&lt;br /&gt;
 git rebase ole-upstream/master&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
You can now delete the fresh clone, it has done its job.  Or leave it for ease-of-use for next rebase.&lt;br /&gt;
&lt;br /&gt;
Now update your bare repo on bitpost, to keep things in sync.&lt;br /&gt;
 git fetch origin master:master -f&lt;br /&gt;
&lt;br /&gt;
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&#039;s what you want)  It is the gitflow way!&lt;br /&gt;
&lt;br /&gt;
Push your new branch to bare, then push bare to GitLab via something like:&lt;br /&gt;
 git push --set-upstream origin release/abt-0.0.3&lt;br /&gt;
&lt;br /&gt;
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!)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://gitlab.com/someauthor/theprojectiforked&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
If you haven&#039;t done so, in GitLab, go to [https://gitlab.com/moodboom/Simple-WebSocket-Server/-/settings/repository#js-protected-branches-settings the &amp;quot;Protected Branch&amp;quot; settings] and remove protection from master - it&#039;s just a fact that you&#039;re going to need to force-push to master.&lt;br /&gt;
&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitLab. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
You will want to force-fetch to update the bare repo you may have on bitpost, DO THIS NOW or you will screw things up badly later:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git fetch origin master:master -f&lt;br /&gt;
You should also force-update ALL your dev repos, NOW, for the same reason:&lt;br /&gt;
 git reset --hard HEAD^^^^^^ &amp;amp;&amp;amp; git pull&lt;br /&gt;
NOTE that you may need to remove a remote-tracking branch if you don&#039;t need it any more.  It&#039;s stupidly painful to get right, eg:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git branch -rd eidheim/Simple-WebSocket-Server/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitHub fork&lt;br /&gt;
|-&lt;br /&gt;
| From [http://stackoverflow.com/a/7244456/717274 so...]&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://github.com/someauthor/theprojectiforked.git&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitHub. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
Now master has the latest commits from the fork origin.  You can rebase onto it, if you&#039;ve been working in a branch (good):&lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git rebase master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Clone a bare repo (eg github, gitlab, bb) into a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Say you want a bare repo to be shared by all your dev environments, but you need to push/pull THAT from a central bare repo, too.&lt;br /&gt;
 git clone --bare --shared git@bitbucket.org:equityshift/es-demo.git&lt;br /&gt;
 cd es-demo.git&lt;br /&gt;
 git config remote.origin.fetch &amp;quot;+*:*&amp;quot;&lt;br /&gt;
 git fetch --all&lt;br /&gt;
I was surprised that this was difficult at all, and may still have some lessons to learn...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch on server, pull to client&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 # ON CENTRAL SERVER&lt;br /&gt;
 git checkout master # as needed; we are assuming that master is clean enough as a starting point&lt;br /&gt;
 git checkout -b mynewbranchy&lt;br /&gt;
 &lt;br /&gt;
 # HOWEVER, use this instead if you need a new &amp;quot;clean&amp;quot; repo and even master is dirty...&lt;br /&gt;
 # You need the rm because git &amp;quot;leaves your working folder intact&amp;quot;.&lt;br /&gt;
 git checkout --orphan mynewbranchy&lt;br /&gt;
 git rm -rf .&lt;br /&gt;
 &lt;br /&gt;
 # ON CLIENT&lt;br /&gt;
 git pull&lt;br /&gt;
 git checkout -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
 # if files are in the way from the previously checked-out branch, you can force it...&lt;br /&gt;
 git checkout -f -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merge changes in a single file&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/11593308/717274 here].  &lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git checkout --patch develop my/single/file.cpp&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove old branches&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/23961231/717274 here].  &lt;br /&gt;
Remote:&lt;br /&gt;
 git push origin --delete &amp;lt;branch&amp;gt;&lt;br /&gt;
Local:&lt;br /&gt;
 git branch -d &amp;lt;branch&amp;gt;&lt;br /&gt;
 git fetch &amp;lt;remote&amp;gt; --prune # Delete multiple obsolete tracking branches&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Work with two local repos&lt;br /&gt;
|-&lt;br /&gt;
| Set up a remote, then fetch it as master.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout --track otherplace/master # or other branch as needed; this creates the branch and sets remote in one step, cool&lt;br /&gt;
Set up a remote, then fetch it into a non-master branch, and push it to the active origin.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout otherplace/master # creates it detached, good because we need to name the new branch something other than master&lt;br /&gt;
 git checkout -b new_otherplace_branchname # creates new local branch with a good name&lt;br /&gt;
 git push --set-upstream origin new_otherplace_branchname # takes the branch from the OLD origin and pushes it to the ACTIVE origin, cool!&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Pull when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
| This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo:&lt;br /&gt;
 git fetch --all&lt;br /&gt;
 git reset --hard origin/mymatchingbranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
   git checkout -b bj143 origin/bj143&lt;br /&gt;
      git : error: The following untracked working tree files would be overwritten by checkout:&lt;br /&gt;
      (etc)&lt;br /&gt;
   &lt;br /&gt;
   TOTAL PURGE FIX (too much):&lt;br /&gt;
      git clean  -d  -fn &amp;quot;&amp;quot;&lt;br /&gt;
         -d dirs too&lt;br /&gt;
         -f force, required&lt;br /&gt;
         -x include ignored files (don&#039;t use this)&lt;br /&gt;
         -n dry run&lt;br /&gt;
   &lt;br /&gt;
   BEST FIX (just overwrite what is in the way):&lt;br /&gt;
      git checkout -f -b bj143 origin/bj143&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Recreate repo&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git clone ssh://m@thedigitalmachine.com/home/m/development/thedigitalage/ampache-with-hangthedj-module&lt;br /&gt;
 cd ampache-with-hangthedj-module&lt;br /&gt;
 git checkout -b daily_grind origin/daily_grind&lt;br /&gt;
If you already have the daily_grind branches and just need to connect them:&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Connect to origin after the fact&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git remote add origin ssh:// m@bitpost.com/home/m/development/logs&lt;br /&gt;
 git fetch&lt;br /&gt;
     From ssh:// bitpost/home/m/development/logs&lt;br /&gt;
      * [new branch]      daily_grind -&amp;gt; origin/daily_grind&lt;br /&gt;
      * [new branch]      master     -&amp;gt; origin/master&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git branch -u origin/master master&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ignore local and remote changes to a file &lt;br /&gt;
|-&lt;br /&gt;
| This is helpful for conf files that need local-specific modifications that shouldn&#039;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].&lt;br /&gt;
&lt;br /&gt;
        PREVENT COMMIT OF CHANGES TO A LOCAL FILE&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
        git update-index --skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        RESET TO GET CHANGES AGAIN&lt;br /&gt;
        --------------------------&lt;br /&gt;
        git update-index --no-skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        LIST SKIPPED FILES&lt;br /&gt;
        ------------------&lt;br /&gt;
        git ls-files -v . | grep ^S&lt;br /&gt;
        S app/views/_partials/jsIncludes.scala.html&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Replace name and email of last commit&lt;br /&gt;
|-&lt;br /&gt;
| Reset the name and email of the last commit, when you realize you forgot to set them first:&lt;br /&gt;
 git commit --amend --author=&amp;quot;First Last &amp;lt;email&amp;gt;&amp;quot; --no-edit&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Simple tagging (when not using git-sync)&lt;br /&gt;
|-&lt;br /&gt;
| To add and push a tag to HEAD:&lt;br /&gt;
 git tag -a 1.2.0 -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
To add and push a tag attached to a commit with current time as timestamp:&lt;br /&gt;
 git tag -a 1.2.0 1bc92e2f -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
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]:&lt;br /&gt;
 # Set the HEAD to the old commit that we want to tag&lt;br /&gt;
 git checkout 9fceb02&lt;br /&gt;
 &lt;br /&gt;
 # temporarily set the date to the date of the HEAD commit, and add the tag&lt;br /&gt;
 GIT_COMMITTER_DATE=&amp;quot;$(git show --format=%aD | head -1)&amp;quot; \&lt;br /&gt;
 git tag -a v1.2 -m&amp;quot;v1.2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # push to origin&lt;br /&gt;
 git push origin --tags&lt;br /&gt;
 &lt;br /&gt;
 # set HEAD back to whatever you want it to be&lt;br /&gt;
 git checkout master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove a tag&lt;br /&gt;
|-&lt;br /&gt;
| This has a long clumsy history, but these instructions should be good into the future.&lt;br /&gt;
&lt;br /&gt;
To remove remote tag(s):&lt;br /&gt;
 git push --delete origin tag YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
Remove tag(s) locally:&lt;br /&gt;
  git tag -d YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Changing branches in a project with submodules&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 # always reset the @*$ submodules to proper commits&lt;br /&gt;
 git checkout develop &amp;amp;&amp;amp; git submodule update&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Hard-reset a misbehaving submodule to parent commit version&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git submodule deinit -f .&lt;br /&gt;
 git submodule update --init&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CONFIGURATION ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set name and email&lt;br /&gt;
|-&lt;br /&gt;
| Globally on one machine (note the machine name at end of user name):&lt;br /&gt;
 git config --global user.email m@thedigitalmachine.com;  git config user.name &amp;quot;Michael Behrns-Miller [cast]&amp;quot;&lt;br /&gt;
Override for a repository:&lt;br /&gt;
 git config user.email mbm@equityshift.io;  git config user.name &amp;quot;MBM [cast]&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default root to main not master&lt;br /&gt;
|-&lt;br /&gt;
| I love the idea of a kinder root name, suck it up alt-right down-punchers, lol.&lt;br /&gt;
Configure it to always happen:&lt;br /&gt;
 git config --global init.defaultBranch main&lt;br /&gt;
Fix it for a newly initialized repository:&lt;br /&gt;
 git branch -m main&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - ONLY PUSH CURRENT doh&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.default current&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - always create remote of a local branch name on push&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.autoSetupRemote true&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - allow push -f&lt;br /&gt;
|-&lt;br /&gt;
| When did it become necessary to configure the upstream to allow this?&lt;br /&gt;
 git config receive.denyNonFastForwards false # to allow git push -f&lt;br /&gt;
 git config receive.denyNonFastForwards true # to turn that back off, good practice i guess&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Visual difftool and mergetool setup&lt;br /&gt;
|-&lt;br /&gt;
| Meld is purdy, let&#039;s kick its tires.  Hope it actually works...&lt;br /&gt;
 git config --global diff.tool meld&lt;br /&gt;
 git config --global merge.tool meld&lt;br /&gt;
 git config --global --add difftool.prompt false&lt;br /&gt;
I used to set up kdiff3 manually, like this... (gross)&lt;br /&gt;
* LINUX - put this in ~/.gitconfig&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 &lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* WINDOZE&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* LINUX Before - What a ridiculous pita... copy this into .git/config...&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert to a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Start with a normal git repo via [git init]; add your files, get it all set up.  Then do this:&lt;br /&gt;
 cd repo&lt;br /&gt;
Now you can copy-paste this...&lt;br /&gt;
 mv .git .. &amp;amp;&amp;amp; rm -fr *&lt;br /&gt;
 mv ../.git .&lt;br /&gt;
 mv .git/* .&lt;br /&gt;
 rmdir .git&lt;br /&gt;
 git config --bool core.bare true&lt;br /&gt;
 cd ..&lt;br /&gt;
Don&#039;t copy/paste these, you need to change repo name...&lt;br /&gt;
 mv repo repo.git # rename it for clarity&lt;br /&gt;
 git clone repo.git # (optional, if you want a live repo on the server where you have the bare repo)&lt;br /&gt;
Then you can clean up old branches like daily and daily_grind, as needed.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert bare to a mirror of remote (github, facebook, etc)&lt;br /&gt;
|-&lt;br /&gt;
| You need a bare mirror repo if you want to take someone else&#039;s repo and create your own bare to work from.&lt;br /&gt;
If you did NOT specify --mirror when you first created the bare repo, you can convert to a mirror by adding these last two lines to config, underneath url:&lt;br /&gt;
 [remote &amp;quot;origin&amp;quot;]&lt;br /&gt;
    url = git@github.com:facebook/proxygen.git&lt;br /&gt;
    fetch = +refs/*:refs/*&lt;br /&gt;
    mirror = true&lt;br /&gt;
Now you can fetch from the bare repo:&lt;br /&gt;
 git fetch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create merge-to command&lt;br /&gt;
|-&lt;br /&gt;
| Add this handy alias command to all git repos&#039; .config file...&lt;br /&gt;
 [alias]&lt;br /&gt;
     merge-to = &amp;quot;!gitmergeto() { export tmp_branch=`git branch | grep &#039;* &#039; | tr -d &#039;* &#039;` &amp;amp;&amp;amp; git checkout $1 &amp;amp;&amp;amp; git merge $tmp_branch &amp;amp;&amp;amp; git checkout $tmp_branch; unset tmp_branch; }; gitmergeto&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix github diverge from local bare repo following README.md edit&lt;br /&gt;
|-&lt;br /&gt;
| Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling.&lt;br /&gt;
Fixing it is a PAIN in the ASS, you have to create a new local repo and pull github into that, pull in from your other local repo, push to github, pull to your bare... &lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git quick-http-with-readme-conflict&lt;br /&gt;
 git remote add local ../quick-http&lt;br /&gt;
 git fetch local&lt;br /&gt;
 git merge local/master # merge in changes, likely trivial&lt;br /&gt;
 git push # pushes back to github&lt;br /&gt;
 cd ..&lt;br /&gt;
 mv quick-http.git quick-http.git__gone-out-of-sync-fu-github-readme-editor&lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git --bare&lt;br /&gt;
 cp quick-http.git__gone-out-of-sync-fu-github-readme-editor/config quick-http.git/&lt;br /&gt;
And that MIGHT get you on your way... but I would no longer trust ANY of your local repos...&lt;br /&gt;
This is a serious pita.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows configure notepad++ editor&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 git config --global core.editor &amp;quot;&#039;C:/Program Files (x86)/Notepad++/notepad++.exe&#039; -multiInst -notabbar -nosession -noPlugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstreams&lt;br /&gt;
|-&lt;br /&gt;
| Use this to cause AUTOMATIC push/pull to a second origin:&lt;br /&gt;
 git remote set-url origin --push --add user1@repo1&lt;br /&gt;
 git remote set-url origin --push --add user2@repo2&lt;br /&gt;
 git remote -v show&lt;br /&gt;
Leave out --push if you want to pull as well... but I&#039;d be careful, it&#039;s better if code is changed in one client with this config, and then pushed to the multiple origins from there.  Otherwise, things are GOING TO GET SYNCY-STINKY.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Git branching strategies ===&lt;br /&gt;
==== Simplified Gitflow ====&lt;br /&gt;
This is awesome, tight, and well-capable of handling any app with a single primary release (like a website).&lt;br /&gt;
                         RELEASE TAG&lt;br /&gt;
 o----------------------------o-----------------o------------o------&amp;gt; MASTER&lt;br /&gt;
  \                          /  \                \----------/ HOTFIX&lt;br /&gt;
   \                        /    \                          \&lt;br /&gt;
    \----------------------/      \--------------------o-----o------&amp;gt; DEVELOP&lt;br /&gt;
                                   \                  /&lt;br /&gt;
                                    \----------------/ FEATURE&lt;br /&gt;
&lt;br /&gt;
Read more [https://medium.com/goodtogoat/simplified-git-flow-5dc37ba76ea8 here] and [https://gist.github.com/vxhviet/9c4a522921ad857406033c4125f343a5 here].&lt;br /&gt;
&lt;br /&gt;
==== Gitflow ====&lt;br /&gt;
I was a die-hard believer in gitflow for a while.  It&#039;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]...&lt;br /&gt;
[[File:Git for nice release planning.png]]&lt;br /&gt;
&lt;br /&gt;
=== LFS ===&lt;br /&gt;
Just don&#039;t use it.  It&#039;s shite.  If you get stuck working with a repo that requires it, and you are using ssh on linux which just won&#039;t work with LFS... you will probably end up with a damaged repo.  Fix it with this:&lt;br /&gt;
 git read-tree HEAD &amp;amp;&amp;amp; GIT_LFS_SKIP_SMUDGE=1 git checkout -f HEAD&lt;br /&gt;
After that, use &#039;&#039;&#039;GIT_LFS_SKIP_SMUDGE=1&#039;&#039;&#039; during any git command:&lt;br /&gt;
 GIT_LFS_SKIP_SMUDGE=1 git pull # etc.&lt;br /&gt;
&lt;br /&gt;
=== My git pages (older) ===&lt;br /&gt;
[[Track your changes to an open-source project with git]]&lt;br /&gt;
&lt;br /&gt;
[[Using git on Windows]]&lt;br /&gt;
&lt;br /&gt;
[[Portable git]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Git&amp;diff=7921</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Git&amp;diff=7921"/>
		<updated>2026-01-05T19:41:02Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== TASKS ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! New shared central bare repo&lt;br /&gt;
|-&lt;br /&gt;
| On central server (aka morosoph):&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git init --bare --shared mynewthang.git&lt;br /&gt;
On development box&lt;br /&gt;
 cd development(...)&lt;br /&gt;
 git clone morosoph:development/mynewthang.git&lt;br /&gt;
 # this will create a new empty repo with no branch yet&lt;br /&gt;
 # TO CREATE MASTER BRANCH (this is the only way):&lt;br /&gt;
 # create files, git add, git commit, git push&lt;br /&gt;
Back on bitpost&lt;br /&gt;
 git clone mynewthang.git # to create a working copy on server, if desired&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! create shared central repo for existing code&lt;br /&gt;
|-&lt;br /&gt;
| Create a bare repo with .git suffix&lt;br /&gt;
 git init --bare --shared mything.git&lt;br /&gt;
Go to existing code and clone the repo next to it, with a temp name.  &lt;br /&gt;
Move .git into the existing code.&lt;br /&gt;
Add code, add a .gitignore as needed, and you&#039;re all set.&lt;br /&gt;
 cd mything/..&lt;br /&gt;
 git clone (bare-repo-host-and-path)mything.git mything-temp&lt;br /&gt;
 mv mything-temp/.git mything/&lt;br /&gt;
 rm -rf mything-temp&lt;br /&gt;
 cd mything&lt;br /&gt;
 code .gitignore # as needed&lt;br /&gt;
 git add (whatever you want to track)&lt;br /&gt;
 git commit -a -m &amp;quot;init repo&amp;quot; &amp;amp;&amp;amp; git push&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fetch a branch from remote without checking it out&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are rebasing a feature branch.&lt;br /&gt;
 git fetch origin develop:develop&lt;br /&gt;
You would think &amp;lt;code&amp;gt;git fetch --all&amp;lt;/code&amp;gt; would do it but does not (it fetches the active branch from &#039;&#039;all origins&#039;&#039; - seriously wtf, who ever wants THAT??).&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Completely reset an out-of-sync branch to 100% match the remote&lt;br /&gt;
|-&lt;br /&gt;
| 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:&lt;br /&gt;
 git reset --hard origin/thebranchname&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default branch of a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| If you want the default branch of a bare repo to be something other than master:&lt;br /&gt;
 git branch&lt;br /&gt;
  * master&lt;br /&gt;
    moodboom-quick-http&lt;br /&gt;
 git symbolic-ref HEAD refs/heads/moodboom-quick-http&lt;br /&gt;
 git branch&lt;br /&gt;
    master&lt;br /&gt;
  * moodboom-quick-http&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Get a file from another branch&lt;br /&gt;
|-&lt;br /&gt;
| Grab the latest version in otherBranch and dump it into your current branch main:&lt;br /&gt;
 git switch main&lt;br /&gt;
 git restore --source otherBranch -- myfile.js&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Find a file across branches&lt;br /&gt;
|-&lt;br /&gt;
| It&#039;s clunky, two steps, and you have to glob out the whole fucking name:&lt;br /&gt;
 # get the commits that involved the filename&lt;br /&gt;
 git log --all -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # even better, get the filenames too, and see if it was added or removed:&lt;br /&gt;
 git log --all --stat -- &#039;**/*namebits*&#039;&lt;br /&gt;
 # now find the branch with one of those commits:&lt;br /&gt;
 git branch -a --contains #commithash#&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gitflow&lt;br /&gt;
|-&lt;br /&gt;
| Gitflow is awesome, using it myself and everywhere I work these days (2020).&lt;br /&gt;
* Devs work out of develop branch&lt;br /&gt;
* Devs create feature branches off develop for any decent-sized work&lt;br /&gt;
* Once develop is stable and you are ready for a release:&lt;br /&gt;
 git tag -a -m &amp;quot;#MAJOR#.#MINOR#&amp;quot;.0 #MAJOR#.#MINOR#.0&lt;br /&gt;
 git checkout -b release/release_#MAJOR#.#MINOR#&lt;br /&gt;
 git push --set-upstream origin release_#MAJOR#.#MINOR#&lt;br /&gt;
 git checkout master &amp;amp;&amp;amp; git merge release/release_#MAJOR#.#MINOR# &amp;amp;&amp;amp; git push&lt;br /&gt;
 git checkout develop # and get back to it!&lt;br /&gt;
* Do hotfixes as needed in release branch, tagged #MAJOR#.#MINOR#.++, merged back into master and develop&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Interactive rebase with squash&lt;br /&gt;
|-&lt;br /&gt;
| Excellent to do when on your own feature branch.  Illegal to do if branch is shared AT ALL!&lt;br /&gt;
 git rebase -i myparentbranch&lt;br /&gt;
 # work through squash and merge - gitlens may help with squash if you use vscode for EDITOR&lt;br /&gt;
 git push -f&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Push any branch from bare to origin&lt;br /&gt;
|-&lt;br /&gt;
| Good for when you are force-pushing a branch rebase.&lt;br /&gt;
 git push [-f] origin mybranch:mybranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gitlab-repo &amp;lt; shared-bare-repo &amp;lt; clients&lt;br /&gt;
|-&lt;br /&gt;
| This is my development setup.  I don&#039;t want to have to use gitlab as the source of truth on my LAN, it just gets in the way.  But I do push code up there so I can share with others.&lt;br /&gt;
&lt;br /&gt;
* Create the gitlab project with repo support.&lt;br /&gt;
* Create a new shared bare repo on LAN.  Configure the gitlab repo as upstream.&lt;br /&gt;
* Clone shared-bare repo to a client.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstream config example&lt;br /&gt;
|-&lt;br /&gt;
| If you edit a file in GitLab, you may need to pull it from remote &amp;quot;gitlab&amp;quot; and push it to remote &amp;quot;sc&amp;quot;, like this:&lt;br /&gt;
 git fetch gitlab develop:develop&lt;br /&gt;
 git push sc&lt;br /&gt;
This assumes you have something like the following in your config:&lt;br /&gt;
 [remote &amp;quot;sc&amp;quot;]&lt;br /&gt;
        url = git@shitcutter.com:the-digital-age/rad-scripts.git&lt;br /&gt;
        fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;github.com&amp;quot;]&lt;br /&gt;
	url = git@github.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
 [remote &amp;quot;gitlab.com&amp;quot;]&lt;br /&gt;
	url = git@gitlab.com:moodboom/rad-scripts.git&lt;br /&gt;
	fetch = +refs/heads/*:refs/remotes/origin/*&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merging conflicts after diverging&lt;br /&gt;
|-&lt;br /&gt;
| Revert local changes in a file to HEAD&lt;br /&gt;
 git checkout -- path/to/file.txt&lt;br /&gt;
Discard ALL LOCAL COMMITS and get the (possibly diverged) remote instead&lt;br /&gt;
 git reset --hard origin/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and push a feature branch&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
 git checkout -b feature/whiz-bang&lt;br /&gt;
 &lt;br /&gt;
 # Do this ONCE: git config --global push.default current&lt;br /&gt;
 # From then on:&lt;br /&gt;
 git push -u&lt;br /&gt;
 &lt;br /&gt;
 # OR, if you don&#039;t want the config, you have to be more specific:&lt;br /&gt;
 # git push -u origin feature/whiz-bang&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab GITFLOW fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
&lt;br /&gt;
This is very easy if you have left the master branch alone for the parent&#039;s commits, and keep your add-on commits in a release-x.x branch, as we have for SWS and SWSS.&lt;br /&gt;
&lt;br /&gt;
 cdl&lt;br /&gt;
 # Clone local repo directly from GitLab (already done on cobra)&lt;br /&gt;
 git clone git@gitlab.com:moodboom/Simple-Web-Server.git SWS-gitlab-moodboom&lt;br /&gt;
 cd SWS-gitlab-moodboom&lt;br /&gt;
 # make sure master is checked out&lt;br /&gt;
 git branch&lt;br /&gt;
 # add parent as remote&lt;br /&gt;
 git remote add ole-upstream git@gitlab.com:eidheim/Simple-Web-Server.git&lt;br /&gt;
 git fetch ole-upstream&lt;br /&gt;
 git rebase ole-upstream/master&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
You can now delete the fresh clone, it has done its job.  Or leave it for ease-of-use for next rebase.&lt;br /&gt;
&lt;br /&gt;
Now update your bare repo on bitpost, to keep things in sync.&lt;br /&gt;
 git fetch origin master:master -f&lt;br /&gt;
&lt;br /&gt;
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&#039;s what you want)  It is the gitflow way!&lt;br /&gt;
&lt;br /&gt;
Push your new branch to bare, then push bare to GitLab via something like:&lt;br /&gt;
 git push --set-upstream origin release/abt-0.0.3&lt;br /&gt;
&lt;br /&gt;
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!)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitLab fork&lt;br /&gt;
|-&lt;br /&gt;
| NOTE: This doesn&#039;t work from a bitpost bare repo, so you need to make a new direct clone of your GitLab fork, first, if you don&#039;t have one yet.&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://gitlab.com/someauthor/theprojectiforked&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
If you haven&#039;t done so, in GitLab, go to [https://gitlab.com/moodboom/Simple-WebSocket-Server/-/settings/repository#js-protected-branches-settings the &amp;quot;Protected Branch&amp;quot; settings] and remove protection from master - it&#039;s just a fact that you&#039;re going to need to force-push to master.&lt;br /&gt;
&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitLab. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
You will want to force-fetch to update the bare repo you may have on bitpost, DO THIS NOW or you will screw things up badly later:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git fetch origin master:master -f&lt;br /&gt;
You should also force-update ALL your dev repos, NOW, for the same reason:&lt;br /&gt;
 git reset --hard HEAD^^^^^^ &amp;amp;&amp;amp; git pull&lt;br /&gt;
NOTE that you may need to remove a remote-tracking branch if you don&#039;t need it any more.  It&#039;s stupidly painful to get right, eg:&lt;br /&gt;
 [Simple-WebSocket-Server.git] git branch -rd eidheim/Simple-WebSocket-Server/master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! getting upstream commits into your GitHub fork&lt;br /&gt;
|-&lt;br /&gt;
| From [http://stackoverflow.com/a/7244456/717274 so...]&lt;br /&gt;
Add the remote, call it something specific:&lt;br /&gt;
 git remote add someauthor-upstream https://github.com/someauthor/theprojectiforked.git&lt;br /&gt;
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:&lt;br /&gt;
 git fetch someauthor-upstream&lt;br /&gt;
Get on the branch where you are tracking the rebase.  Typically your master branch but can be whatever:&lt;br /&gt;
 git checkout tlsv12 # or master or next or...&lt;br /&gt;
Rewrite your branch so that any commits of yours that aren&#039;t already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you&#039;ll screw up the upstream!):&lt;br /&gt;
 git rebase someauthor-upstream/master&lt;br /&gt;
IF the branch that was the target of the rebase existed, force the push in order to push it to your own forked repository on GitHub. You only need to use the -f the first time after you&#039;ve rebased:&lt;br /&gt;
 git push -f origin master&lt;br /&gt;
ELSE if the branch you merged into is a new creation, set its upstream when you push:&lt;br /&gt;
 git push --set-upstream origin tlsv12&lt;br /&gt;
Now master has the latest commits from the fork origin.  You can rebase onto it, if you&#039;ve been working in a branch (good):&lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git rebase master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Clone a bare repo (eg github, gitlab, bb) into a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Say you want a bare repo to be shared by all your dev environments, but you need to push/pull THAT from a central bare repo, too.&lt;br /&gt;
 git clone --bare --shared git@bitbucket.org:equityshift/es-demo.git&lt;br /&gt;
 cd es-demo.git&lt;br /&gt;
 git config remote.origin.fetch &amp;quot;+*:*&amp;quot;&lt;br /&gt;
 git fetch --all&lt;br /&gt;
I was surprised that this was difficult at all, and may still have some lessons to learn...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch on server, pull to client&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 # ON CENTRAL SERVER&lt;br /&gt;
 git checkout master # as needed; we are assuming that master is clean enough as a starting point&lt;br /&gt;
 git checkout -b mynewbranchy&lt;br /&gt;
 &lt;br /&gt;
 # HOWEVER, use this instead if you need a new &amp;quot;clean&amp;quot; repo and even master is dirty...&lt;br /&gt;
 # You need the rm because git &amp;quot;leaves your working folder intact&amp;quot;.&lt;br /&gt;
 git checkout --orphan mynewbranchy&lt;br /&gt;
 git rm -rf .&lt;br /&gt;
 &lt;br /&gt;
 # ON CLIENT&lt;br /&gt;
 git pull&lt;br /&gt;
 git checkout -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
 # if files are in the way from the previously checked-out branch, you can force it...&lt;br /&gt;
 git checkout -f -b mynewbranchy origin/mynewbranchy&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Merge changes in a single file&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/11593308/717274 here].  &lt;br /&gt;
 git checkout mybranch&lt;br /&gt;
 git checkout --patch develop my/single/file.cpp&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove old branches&lt;br /&gt;
|-&lt;br /&gt;
| Explanation is [https://stackoverflow.com/a/23961231/717274 here].  &lt;br /&gt;
Remote:&lt;br /&gt;
 git push origin --delete &amp;lt;branch&amp;gt;&lt;br /&gt;
Local:&lt;br /&gt;
 git branch -d &amp;lt;branch&amp;gt;&lt;br /&gt;
 git fetch &amp;lt;remote&amp;gt; --prune # Delete multiple obsolete tracking branches&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Work with two local repos&lt;br /&gt;
|-&lt;br /&gt;
| Set up a remote, then fetch it as master.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout --track otherplace/master # or other branch as needed; this creates the branch and sets remote in one step, cool&lt;br /&gt;
Set up a remote, then fetch it into a non-master branch, and push it to the active origin.&lt;br /&gt;
 cd repoToChange&lt;br /&gt;
 git remote add otherplace ../../wherever/../gitrepo&lt;br /&gt;
 git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)&lt;br /&gt;
 git fetch otherplace # gets it all&lt;br /&gt;
 git checkout otherplace/master # creates it detached, good because we need to name the new branch something other than master&lt;br /&gt;
 git checkout -b new_otherplace_branchname # creates new local branch with a good name&lt;br /&gt;
 git push --set-upstream origin new_otherplace_branchname # takes the branch from the OLD origin and pushes it to the ACTIVE origin, cool!&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Pull when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
| This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo:&lt;br /&gt;
 git fetch --all&lt;br /&gt;
 git reset --hard origin/mymatchingbranch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create new branch when untracked files are in the way&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
   git checkout -b bj143 origin/bj143&lt;br /&gt;
      git : error: The following untracked working tree files would be overwritten by checkout:&lt;br /&gt;
      (etc)&lt;br /&gt;
   &lt;br /&gt;
   TOTAL PURGE FIX (too much):&lt;br /&gt;
      git clean  -d  -fn &amp;quot;&amp;quot;&lt;br /&gt;
         -d dirs too&lt;br /&gt;
         -f force, required&lt;br /&gt;
         -x include ignored files (don&#039;t use this)&lt;br /&gt;
         -n dry run&lt;br /&gt;
   &lt;br /&gt;
   BEST FIX (just overwrite what is in the way):&lt;br /&gt;
      git checkout -f -b bj143 origin/bj143&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Recreate repo&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git clone ssh://m@thedigitalmachine.com/home/m/development/thedigitalage/ampache-with-hangthedj-module&lt;br /&gt;
 cd ampache-with-hangthedj-module&lt;br /&gt;
 git checkout -b daily_grind origin/daily_grind&lt;br /&gt;
If you already have the daily_grind branches and just need to connect them:&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Connect to origin after the fact&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git remote add origin ssh:// m@bitpost.com/home/m/development/logs&lt;br /&gt;
 git fetch&lt;br /&gt;
     From ssh:// bitpost/home/m/development/logs&lt;br /&gt;
      * [new branch]      daily_grind -&amp;gt; origin/daily_grind&lt;br /&gt;
      * [new branch]      master     -&amp;gt; origin/master&lt;br /&gt;
 git branch -u origin/daily_grind daily_grind&lt;br /&gt;
 git checkout master&lt;br /&gt;
 git branch -u origin/master master&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ignore local and remote changes to a file &lt;br /&gt;
|-&lt;br /&gt;
| This is helpful for conf files that need local-specific modifications that shouldn&#039;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].&lt;br /&gt;
&lt;br /&gt;
        PREVENT COMMIT OF CHANGES TO A LOCAL FILE&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
        git update-index --skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        RESET TO GET CHANGES AGAIN&lt;br /&gt;
        --------------------------&lt;br /&gt;
        git update-index --no-skip-worktree apps/views/_partials/jsIncludes.scala.html&lt;br /&gt;
 &lt;br /&gt;
        LIST SKIPPED FILES&lt;br /&gt;
        ------------------&lt;br /&gt;
        git ls-files -v . | grep ^S&lt;br /&gt;
        S app/views/_partials/jsIncludes.scala.html&lt;br /&gt;
        -----------------------------------------&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Replace name and email of last commit&lt;br /&gt;
|-&lt;br /&gt;
| Reset the name and email of the last commit, when you realize you forgot to set them first:&lt;br /&gt;
 git commit --amend --author=&amp;quot;First Last &amp;lt;email&amp;gt;&amp;quot; --no-edit&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Simple tagging (when not using git-sync)&lt;br /&gt;
|-&lt;br /&gt;
| To add and push a tag to HEAD:&lt;br /&gt;
 git tag -a 1.2.0 -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
To add and push a tag attached to a commit with current time as timestamp:&lt;br /&gt;
 git tag -a 1.2.0 1bc92e2f -m &amp;quot;1.2.0&amp;quot;&lt;br /&gt;
 git push origin 1.2.0&lt;br /&gt;
&lt;br /&gt;
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]:&lt;br /&gt;
 # Set the HEAD to the old commit that we want to tag&lt;br /&gt;
 git checkout 9fceb02&lt;br /&gt;
 &lt;br /&gt;
 # temporarily set the date to the date of the HEAD commit, and add the tag&lt;br /&gt;
 GIT_COMMITTER_DATE=&amp;quot;$(git show --format=%aD | head -1)&amp;quot; \&lt;br /&gt;
 git tag -a v1.2 -m&amp;quot;v1.2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # push to origin&lt;br /&gt;
 git push origin --tags&lt;br /&gt;
 &lt;br /&gt;
 # set HEAD back to whatever you want it to be&lt;br /&gt;
 git checkout master&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Remove a tag&lt;br /&gt;
|-&lt;br /&gt;
| This has a long clumsy history, but these instructions should be good into the future.&lt;br /&gt;
&lt;br /&gt;
To remove remote tag(s):&lt;br /&gt;
 git push --delete origin tag YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
Remove tag(s) locally:&lt;br /&gt;
  git tag -d YOUR_TAG_NAME TAG_NAME_2 ...&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Changing branches in a project with submodules&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 # always reset the @*$ submodules to proper commits&lt;br /&gt;
 git checkout develop &amp;amp;&amp;amp; git submodule update&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Hard-reset a misbehaving submodule to parent commit version&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git submodule deinit -f .&lt;br /&gt;
 git submodule update --init&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CONFIGURATION ===&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set name and email&lt;br /&gt;
|-&lt;br /&gt;
| Globally on one machine (note the machine name at end of user name):&lt;br /&gt;
 git config --global user.email m@thedigitalmachine.com;  git config user.name &amp;quot;Michael Behrns-Miller [cast]&amp;quot;&lt;br /&gt;
Override for a repository:&lt;br /&gt;
 git config user.email mbm@equityshift.io;  git config user.name &amp;quot;MBM [cast]&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Set default root to main not master&lt;br /&gt;
|-&lt;br /&gt;
| I love the idea of a kinder root name, suck it up alt-right down-punchers, lol.&lt;br /&gt;
Configure it to always happen:&lt;br /&gt;
 git config --global init.defaultBranch main&lt;br /&gt;
Fix it for a newly initialized repository:&lt;br /&gt;
 git branch -m main&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - ONLY PUSH CURRENT doh&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.default current&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - always create remote of a local branch name on push&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
 git config --global push.autoSetupRemote true&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix push behavior - allow push -f&lt;br /&gt;
|-&lt;br /&gt;
| When did it become necessary to configure the upstream to allow this?&lt;br /&gt;
 git config receive.denyNonFastForwards false # to allow git push -f&lt;br /&gt;
 git config receive.denyNonFastForwards true # to turn that back off, good practice i guess&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Visual difftool and mergetool setup&lt;br /&gt;
|-&lt;br /&gt;
| Meld is purdy, let&#039;s kick its tires.  Hope it actually works...&lt;br /&gt;
 git config --global diff.tool meld&lt;br /&gt;
 git config --global merge.tool meld&lt;br /&gt;
 git config --global --add difftool.prompt false&lt;br /&gt;
I used to set up kdiff3 manually, like this... (gross)&lt;br /&gt;
* LINUX - put this in ~/.gitconfig&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 &lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* WINDOZE&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = C:/Progra~1/KDiff3/kdiff3.exe&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
* LINUX Before - What a ridiculous pita... copy this into .git/config...&lt;br /&gt;
 [difftool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [difftool]&lt;br /&gt;
     prompt = false&lt;br /&gt;
 [diff]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
 [mergetool &amp;quot;kdiff3&amp;quot;]&lt;br /&gt;
     path = /usr/bin/kdiff3&lt;br /&gt;
     trustExitCode = false&lt;br /&gt;
 [mergetool]&lt;br /&gt;
     keepBackup = false&lt;br /&gt;
 [merge]&lt;br /&gt;
     tool = kdiff3&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert to a bare repo&lt;br /&gt;
|-&lt;br /&gt;
| Start with a normal git repo via [git init]; add your files, get it all set up.  Then do this:&lt;br /&gt;
 cd repo&lt;br /&gt;
Now you can copy-paste this...&lt;br /&gt;
 mv .git .. &amp;amp;&amp;amp; rm -fr *&lt;br /&gt;
 mv ../.git .&lt;br /&gt;
 mv .git/* .&lt;br /&gt;
 rmdir .git&lt;br /&gt;
 git config --bool core.bare true&lt;br /&gt;
 cd ..&lt;br /&gt;
Don&#039;t copy/paste these, you need to change repo name...&lt;br /&gt;
 mv repo repo.git # rename it for clarity&lt;br /&gt;
 git clone repo.git # (optional, if you want a live repo on the server where you have the bare repo)&lt;br /&gt;
Then you can clean up old branches like daily and daily_grind, as needed.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Convert bare to a mirror of remote (github, facebook, etc)&lt;br /&gt;
|-&lt;br /&gt;
| You need a bare mirror repo if you want to take someone else&#039;s repo and create your own bare to work from.&lt;br /&gt;
If you did NOT specify --mirror when you first created the bare repo, you can convert to a mirror by adding these last two lines to config, underneath url:&lt;br /&gt;
 [remote &amp;quot;origin&amp;quot;]&lt;br /&gt;
    url = git@github.com:facebook/proxygen.git&lt;br /&gt;
    fetch = +refs/*:refs/*&lt;br /&gt;
    mirror = true&lt;br /&gt;
Now you can fetch from the bare repo:&lt;br /&gt;
 git fetch&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create merge-to command&lt;br /&gt;
|-&lt;br /&gt;
| Add this handy alias command to all git repos&#039; .config file...&lt;br /&gt;
 [alias]&lt;br /&gt;
     merge-to = &amp;quot;!gitmergeto() { export tmp_branch=`git branch | grep &#039;* &#039; | tr -d &#039;* &#039;` &amp;amp;&amp;amp; git checkout $1 &amp;amp;&amp;amp; git merge $tmp_branch &amp;amp;&amp;amp; git checkout $tmp_branch; unset tmp_branch; }; gitmergeto&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Fix github diverge from local bare repo following README.md edit&lt;br /&gt;
|-&lt;br /&gt;
| Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling.&lt;br /&gt;
Fixing it is a PAIN in the ASS, you have to create a new local repo and pull github into that, pull in from your other local repo, push to github, pull to your bare... &lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git quick-http-with-readme-conflict&lt;br /&gt;
 git remote add local ../quick-http&lt;br /&gt;
 git fetch local&lt;br /&gt;
 git merge local/master # merge in changes, likely trivial&lt;br /&gt;
 git push # pushes back to github&lt;br /&gt;
 cd ..&lt;br /&gt;
 mv quick-http.git quick-http.git__gone-out-of-sync-fu-github-readme-editor&lt;br /&gt;
 git clone git@github.com:moodboom/quick-http.git --bare&lt;br /&gt;
 cp quick-http.git__gone-out-of-sync-fu-github-readme-editor/config quick-http.git/&lt;br /&gt;
And that MIGHT get you on your way... but I would no longer trust ANY of your local repos...&lt;br /&gt;
This is a serious pita.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows configure notepad++ editor&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
 git config --global core.editor &amp;quot;&#039;C:/Program Files (x86)/Notepad++/notepad++.exe&#039; -multiInst -notabbar -nosession -noPlugin&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Multiple upstreams&lt;br /&gt;
|-&lt;br /&gt;
| Use this to cause AUTOMATIC push/pull to a second origin:&lt;br /&gt;
 git remote set-url origin --push --add user1@repo1&lt;br /&gt;
 git remote set-url origin --push --add user2@repo2&lt;br /&gt;
 git remote -v show&lt;br /&gt;
Leave out --push if you want to pull as well... but I&#039;d be careful, it&#039;s better if code is changed in one client with this config, and then pushed to the multiple origins from there.  Otherwise, things are GOING TO GET SYNCY-STINKY.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Git branching strategies ===&lt;br /&gt;
==== Simplified Gitflow ====&lt;br /&gt;
This is awesome, tight, and well-capable of handling any app with a single primary release (like a website).&lt;br /&gt;
                         RELEASE TAG&lt;br /&gt;
 o----------------------------o-----------------o------------o------&amp;gt; MASTER&lt;br /&gt;
  \                          /  \                \----------/ HOTFIX&lt;br /&gt;
   \                        /    \                          \&lt;br /&gt;
    \----------------------/      \--------------------o-----o------&amp;gt; DEVELOP&lt;br /&gt;
                                   \                  /&lt;br /&gt;
                                    \----------------/ FEATURE&lt;br /&gt;
&lt;br /&gt;
Read more [https://medium.com/goodtogoat/simplified-git-flow-5dc37ba76ea8 here] and [https://gist.github.com/vxhviet/9c4a522921ad857406033c4125f343a5 here].&lt;br /&gt;
&lt;br /&gt;
==== Gitflow ====&lt;br /&gt;
I was a die-hard believer in gitflow for a while.  It&#039;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]...&lt;br /&gt;
[[File:Git for nice release planning.png]]&lt;br /&gt;
&lt;br /&gt;
=== LFS ===&lt;br /&gt;
Just don&#039;t use it.  It&#039;s shite.  If you get stuck working with a repo that requires it, and you are using ssh on linux which just won&#039;t work with LFS... you will probably end up with a damaged repo.  Fix it with this:&lt;br /&gt;
 git read-tree HEAD &amp;amp;&amp;amp; GIT_LFS_SKIP_SMUDGE=1 git checkout -f HEAD&lt;br /&gt;
After that, use &#039;&#039;&#039;GIT_LFS_SKIP_SMUDGE=1&#039;&#039;&#039; during any git command:&lt;br /&gt;
 GIT_LFS_SKIP_SMUDGE=1 git pull # etc.&lt;br /&gt;
&lt;br /&gt;
=== My git pages (older) ===&lt;br /&gt;
[[Track your changes to an open-source project with git]]&lt;br /&gt;
&lt;br /&gt;
[[Using git on Windows]]&lt;br /&gt;
&lt;br /&gt;
[[Portable git]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7920</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7920"/>
		<updated>2026-01-02T21:16:32Z</updated>

		<summary type="html">&lt;p&gt;M: /* Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately [https://claude.ai/settings/data-privacy-controls turn this off], or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7919</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7919"/>
		<updated>2026-01-02T21:15:39Z</updated>

		<summary type="html">&lt;p&gt;M: /* Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately turn this off, or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
There&#039;s more crazy privacy stuff to watch out for [https://console.anthropic.com/settings/privacy here].&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7918</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7918"/>
		<updated>2026-01-01T15:20:23Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately turn this off, or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
=== Billing ===&lt;br /&gt;
&lt;br /&gt;
* I started with the API usage billing.&lt;br /&gt;
* It&#039;s expensive.  I chewed up $5 pretty fast, so I added $25 more.&lt;br /&gt;
* It chewed up $14 of the $30 building sceneKitScrap.  Not terrible value, not great either.&lt;br /&gt;
* I switched to the Pro plan for $20/month.&lt;br /&gt;
* TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7917</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7917"/>
		<updated>2026-01-01T14:28:56Z</updated>

		<summary type="html">&lt;p&gt;M: /* Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately turn this off, or it will suck up and train on your code:&lt;br /&gt;
 Settings &amp;gt; Privacy &amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
I started with the API usage billing, it chewed up $35 fast, so I switched to the Pro plan for $20/month.&lt;br /&gt;
&lt;br /&gt;
TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7916</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7916"/>
		<updated>2026-01-01T14:28:28Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately turn this off, or it will suck up and train on your code:&lt;br /&gt;
&lt;br /&gt;
[[File:Claude_Code_DO_NOT_TRAIN_ON_ME.png]]&lt;br /&gt;
&lt;br /&gt;
I started with the API usage billing, it chewed up $35 fast, so I switched to the Pro plan for $20/month.&lt;br /&gt;
&lt;br /&gt;
TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=File:Claude_Code_DO_NOT_TRAIN_ON_ME.png&amp;diff=7915</id>
		<title>File:Claude Code DO NOT TRAIN ON ME.png</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=File:Claude_Code_DO_NOT_TRAIN_ON_ME.png&amp;diff=7915"/>
		<updated>2026-01-01T14:27:48Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7914</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7914"/>
		<updated>2026-01-01T14:27:03Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
WHATEVER YOU CHOOSE, immmediately turn this off, or it will suck up and train on your code:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I started with the API usage billing, it chewed up $35 fast, so I switched to the Pro plan for $20/month.&lt;br /&gt;
&lt;br /&gt;
TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7913</id>
		<title>Claude Code</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Claude_Code&amp;diff=7913"/>
		<updated>2026-01-01T14:24:25Z</updated>

		<summary type="html">&lt;p&gt;M: Created page with &amp;quot;== Installation == Install via bash script from [https://code.claude.com/docs/en/quickstart here]:  curl -fsSL https://claude.ai/install.sh | bash  == Plan == I started with the API usage billing, it chewed up $35 fast, so I switched to the Pro plan for $20/month.  TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
Install via bash script from [https://code.claude.com/docs/en/quickstart here]:&lt;br /&gt;
 curl -fsSL https://claude.ai/install.sh | bash&lt;br /&gt;
&lt;br /&gt;
== Plan ==&lt;br /&gt;
I started with the API usage billing, it chewed up $35 fast, so I switched to the Pro plan for $20/month.&lt;br /&gt;
&lt;br /&gt;
TBD if that will be useful or so limited it is a total waste of time.  Max 5x plan is $100/mo.  Fucking profiteers.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=AI_Coding&amp;diff=7912</id>
		<title>AI Coding</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=AI_Coding&amp;diff=7912"/>
		<updated>2026-01-01T14:16:42Z</updated>

		<summary type="html">&lt;p&gt;M: Created page with &amp;quot;Claude Code  Google Gemini  Microsoft Copilot&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Claude Code]]&lt;br /&gt;
&lt;br /&gt;
[[Google Gemini]]&lt;br /&gt;
&lt;br /&gt;
[[Microsoft Copilot]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Software_reference&amp;diff=7911</id>
		<title>Software reference</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Software_reference&amp;diff=7911"/>
		<updated>2026-01-01T14:16:08Z</updated>

		<summary type="html">&lt;p&gt;M: /* TOOLS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== TASKS ==&lt;br /&gt;
&lt;br /&gt;
[[Video Editing]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== APPS ==&lt;br /&gt;
&lt;br /&gt;
A/V: [[Kodi]] - [[VLC]] - [[Blender]] - [[Gimp]] - [[Shotwell]] - [[Davinci Resolve]]&lt;br /&gt;
&lt;br /&gt;
Music: [[FL Studio]] - [[Reaper]] - [[Audacity]] - [[Ampache]] - [[Spotify]] - [[Strawberry]]&lt;br /&gt;
&lt;br /&gt;
Games: [[Steam]] - [[Minecraft]] - [[Twitch]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TOOLS ==&lt;br /&gt;
&lt;br /&gt;
[[AI]]&lt;br /&gt;
&lt;br /&gt;
[[Mediawiki]] - [[Wordpress]] - [[Timewarrior]] - [[Workflowy]]&lt;br /&gt;
&lt;br /&gt;
[[LibreOffice]] - [[qBitTorrent]] - [[Cura]]&lt;br /&gt;
&lt;br /&gt;
[[Visual Studio Code|vscode]] - [[ne]] - [[Cursor]] - [[Qt Creator]] - [[Emacs]] - [[GitLab]]&lt;br /&gt;
&lt;br /&gt;
[[irc]] - [[slack]]- [[pidgin]] - [[XMPP]] - [[Rocket.Chat]] - [[zoom]]&lt;br /&gt;
&lt;br /&gt;
[[i3]] - [[UnixPorn]] - [[terminal]] - [[kitty]] - [[screen]] - [[albert]]&lt;br /&gt;
&lt;br /&gt;
[[HandBrake]] - [[simplescreenrecorder]] - [[vokoscreenNG]] - [[osi]] - [[maim]] - [[copyq]]&lt;br /&gt;
&lt;br /&gt;
[[mame]] - [[Simon]] - [[Kaldi]] - [http://www.question2answer.org/ Q2A]&lt;br /&gt;
&lt;br /&gt;
[[Brave]] - [[Vivaldi]] - [[Tor]] - [[Chrome]] - [[Firefox]] - [[Okular]]&lt;br /&gt;
&lt;br /&gt;
[[DBeaver]] - [[pgadmin4]] - [[Studio 3T]] - [[Sqlite Explorer]]&lt;br /&gt;
&lt;br /&gt;
[[postgres]] - [[sqlite]] - [[mongodb]] - [[mysql]] - [[mariadb]] - [[SQL Server]]&lt;br /&gt;
&lt;br /&gt;
[[Docker]] - [[ninja]] - [[CMake]] - [[gcc]] - [[git]] - [[eslint]]&lt;br /&gt;
&lt;br /&gt;
[[TrueNAS]] - [[Linux software raid]] - [[Wireshark]] - [[Apache]]&lt;br /&gt;
&lt;br /&gt;
[[ssh]] - [[gpg]] - [[haproxy]] - [[dnsmasq]] - [[geth]]&lt;br /&gt;
&lt;br /&gt;
[[proxmox]] - [[SPICE]] - [[vnc]] - [[Remote Desktop]] - [[Remmina]]&lt;br /&gt;
&lt;br /&gt;
[[WireGuard]] - [[TailScale]] - [[OpenVPN]]&lt;br /&gt;
&lt;br /&gt;
[[GCP]] - [[AWS]]&lt;br /&gt;
&lt;br /&gt;
[[systemd]] - [[xrandr]] - [[samba]] - [[fail2ban]] - [[ntp]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Software Under Review]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Software Archive]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! OS installation&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 25.10 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 25.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 24.10 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 24.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu 22.04 upgrade]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Linux barebones quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ventoy|Ventoy ISO boot disk]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Raspberry Pi]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Kali quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Centos quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Cygwin quickstart]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[OS X]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Update gentoo kernel]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Upgrade gentoo]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Windows 10 quickstart&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* [[Cygwin quickstart|Install cygwin]]&lt;br /&gt;
* Disable automatic restarts&lt;br /&gt;
Install Group Policy Editor from an admin Powershell console:&lt;br /&gt;
 @echo off &lt;br /&gt;
 pushd &amp;quot;%~dp0&amp;quot; &lt;br /&gt;
 &lt;br /&gt;
 dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum &amp;gt;List.txt &lt;br /&gt;
 dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum &amp;gt;&amp;gt;List.txt &lt;br /&gt;
 &lt;br /&gt;
 for /f %%i in (&#039;findstr /i . List.txt 2^&amp;gt;nul&#039;) do dism /online /norestart /add-package:&amp;quot;%SystemRoot%\servicing\Packages\%%i&amp;quot; &lt;br /&gt;
 pause&lt;br /&gt;
Run Group Policy Editor to disable restarts:&lt;br /&gt;
 Computer Configuration &amp;gt; Administrative Templates &amp;gt; Windows Components &amp;gt; Windows Update &amp;gt; Configure Automatic Updates&lt;br /&gt;
 (o) Enabled&lt;br /&gt;
 [2] Notify for download and auto install?  Or [3] Auto download and notify for install?  Going with [3], we&#039;ll see.&lt;br /&gt;
 (or...) (o) Enabled: No auto-restart with logged on users for scheduled automatic updates installations&lt;br /&gt;
 ---&lt;br /&gt;
 No auto-restart with logged on users for scheduled automatic updates installation (just in case)&lt;br /&gt;
 (o) Enabled&lt;br /&gt;
 ---&lt;br /&gt;
 (reboot if you had to change it?  or will that wipe it out?  tbd...) &lt;br /&gt;
In a corporate environment, you should quit your job - I mean, you will likely have to redo this after ANY f&#039;in reboot.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Memtest boot disk&lt;br /&gt;
|-&lt;br /&gt;
| It should be on red-on-black flash drive.  Or, [https://www.memtest86.com/download.htm get a fresh download] of USB zip, it includes a Windows exe to create the boot.  Or use the ISO.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Ubuntu upgrade / reinstall notes]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Create and boot from Ubuntu USB&lt;br /&gt;
|-&lt;br /&gt;
| There should always be a boot USB for this in my set, but it needs recreation on new Ubuntu versions...&lt;br /&gt;
# Download the latest 64-bit Ubuntu desktop iso&lt;br /&gt;
# Format a USB drive as FAT (NOT exFAT or NTFS)&lt;br /&gt;
# Burn the iso to the USB, providing a GB of space (we want to add the nvidia driver once booted)&lt;br /&gt;
 sudo usb-creator-gtk&lt;br /&gt;
# Boot with it&lt;br /&gt;
# On startup, select the USB EFI boot option in refind, select &amp;quot;Try Ubuntu&amp;quot;, (on MBPro, hit e and add [ nouveau.noaccel=1] to grub line), hit F10 to start&lt;br /&gt;
# Once it is running, start System Settings, select Software, enable proprietary drivers&lt;br /&gt;
# Install, checking the [download as you go] and [install 3rd party stuff] boxes.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Ubuntu set up networking&lt;br /&gt;
|-&lt;br /&gt;
| Install NetworkManager, as the wpagui UI sucks&lt;br /&gt;
* sudo apt-get install network-manager-gnome&lt;br /&gt;
* YOU MUST remove interfaces from /etc/network/interfaces so wpa gives them up to nm-applet&lt;br /&gt;
* add nm-applet to startup if needed - i don&#039;t think it is needed as it seems to start up automatically now - try rebooting first&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Development_reference&amp;diff=7910</id>
		<title>Development reference</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Development_reference&amp;diff=7910"/>
		<updated>2026-01-01T14:14:41Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Design, programming and version control.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[AI Coding]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Patterns&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Major Objects]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Quick-http]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Continuous Integration]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [http://www.aosabook.org/en/index.html Architecture of major open source apps]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Security]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Model View Controller]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! nosql enhances, not replaces, SQL&lt;br /&gt;
|-&lt;br /&gt;
| Not all data should be denormalized, and not all data should be normalized.  The optimal mix considers the extent of the data.  &lt;br /&gt;
&lt;br /&gt;
* Precise schemas are good when not overdone&lt;br /&gt;
* When a container has an array with a large number of elements, it should be normalized&lt;br /&gt;
* Sparse data and heterogeneous data are the best candidates for denormalization&lt;br /&gt;
&lt;br /&gt;
Postgres with JSON allows an elegant combination of nosql and SQL.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Web design mantra&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
# DESIGN INPUT TO THE INPUT DEVICE &lt;br /&gt;
## respect the input device&lt;br /&gt;
## detect it and use a reasonable default guess&lt;br /&gt;
## allow manual override&lt;br /&gt;
## [mouse/pen]...[finger]&lt;br /&gt;
##  sm-md-lg  ...  sm-md-lg&lt;br /&gt;
# DESIGN VISUALS TO THE SCREEN&lt;br /&gt;
## high-res = SHOW LOTS OF DETAIL&lt;br /&gt;
## responsive, zoomable&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! git central shared repository&lt;br /&gt;
|-&lt;br /&gt;
| Use bare repos for any central shared repositories.  Use the [####.git] suffix on bare repo names.&lt;br /&gt;
&lt;br /&gt;
Bare repositories are designed to be shared.  Maintenance on the central server is easier because you don&#039;t have local files to manage permissions or constant flux.  Plus, you can always have a second repo on the central server where you check out a specific branch (e.g. to serve up with apache).  If you want a dynamically updated central repo, clone the ###.git repo to ###, and add a post-receive hook (see bitpost quick-http.git for a good example).&lt;br /&gt;
&lt;br /&gt;
To configure the repo as shared:&lt;br /&gt;
 git config core.sharedRepository true&lt;br /&gt;
To set it on a new git repo during initial setup, make sure devs are in the same group, and use:&lt;br /&gt;
 git init --shared=group&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Occam&#039;s razor&lt;br /&gt;
|-&lt;br /&gt;
| Among competing hypotheses, the one with the fewest assumptions should be selected.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C++&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Deleting multiple elements in a collection&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* For sequences (vector, list...), best practice is to use the [https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom erase-remove] STL pattern&lt;br /&gt;
* For associative containers (set, map...): just recurse and remove iterators, they won&#039;t muck up the sequence.  [http://stackoverflow.com/questions/800955/remove-if-equivalent-for-stdmap example]&lt;br /&gt;
See MemoryModel::saveDirtyObjectsAsNeeded() for example code.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ Create a portable C/C++ project&lt;br /&gt;
|-&lt;br /&gt;
| Use QtCreator + CMake, both available everywhere!&lt;br /&gt;
    set up:&lt;br /&gt;
        create a Qt project as: New Project-&amp;gt; Non-Qt/Plain C Project (CMake Build)&lt;br /&gt;
            pick the PARENT and use the name of the existing folder&lt;br /&gt;
            set up a build folder in the existing folder, called (base)/qtcreator-release-build&lt;br /&gt;
            it creates CMakeLists.txt (THIS IS BASICALLY THE PROJECT FILE!)&lt;br /&gt;
            also creates main.c or something&lt;br /&gt;
            build it!  make sure it works&lt;br /&gt;
            NOW we can edit CMakeLists.txt - change . to ./src to get it to scan the src folder for code!&lt;br /&gt;
            and easily add &amp;quot;known&amp;quot; libs!  this was all i needed:&lt;br /&gt;
                TARGET_LINK_LIBRARIES(${PROJECT_NAME} pthread websockets)&lt;br /&gt;
            make sure it builds&lt;br /&gt;
            now we want a DEBUG build as well!&lt;br /&gt;
            Projects-&amp;gt;Build&amp;amp;Run-&amp;gt;pick Build in weird Build/Run pillbox-&amp;gt;Edit build configs:&lt;br /&gt;
                Rename: release&lt;br /&gt;
                CMake build dir: Make sure build dir is set to release ie qtcreator-debug-build&lt;br /&gt;
                Add: Clone: release, name: debug&lt;br /&gt;
                    for debug, add a custom build step BEFORE make step:&lt;br /&gt;
                        command: /usr/bin/cmake&lt;br /&gt;
                        args: -DCMAKE_BUILD_TYPE=Debug .&lt;br /&gt;
                        working dir: %{buildDir}&lt;br /&gt;
                        (add it, and move it up above make)&lt;br /&gt;
                        (build em both)&lt;br /&gt;
            Projects-&amp;gt;Build&amp;amp;Run-&amp;gt;pick Run in weird Build/Run pillbox&lt;br /&gt;
                Run Configuration: rename to &amp;quot;{...} release&amp;quot;&lt;br /&gt;
                clone it into &amp;quot;{...} debug&amp;quot;&lt;br /&gt;
                change working dir to match Build path&lt;br /&gt;
                change any needed params&lt;br /&gt;
    Now you should have build+run debug+release configurations, selectable in the weird project icon in bottom of left-side toolbar (&amp;quot;mode selector&amp;quot;)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ in-memory storage of &amp;quot;major&amp;quot; objects&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
    OBSERVATION ONE&lt;br /&gt;
 &lt;br /&gt;
    Consider An Important Qt Design: QObjects cannot normally be copied&lt;br /&gt;
        their copy constructors and assignment operators are private&lt;br /&gt;
        why?  A Qt Object...&lt;br /&gt;
            might have a unique QObject::objectName(). If we copy a Qt Object, what name should we give the copy?&lt;br /&gt;
            has a location in an object hierarchy. If we copy a Qt Object, where should the copy be located?&lt;br /&gt;
            can be connected to other Qt Objects to emit signals to them or to receive signals emitted by them. If we copy a Qt Object, how should we transfer these connections to the copy?&lt;br /&gt;
            can have new properties added to it at runtime that are not declared in the C++ class. If we copy a Qt Object, should the copy include the properties that were added to the original?&lt;br /&gt;
    in other words, a QObject is a pretty serious object that has the ability to be tied to other objects and resources in ways that make copying dangerous&lt;br /&gt;
    isn&#039;t this true of all serious objects?  pretty much&lt;br /&gt;
&lt;br /&gt;
    OBSERVATION TWO&lt;br /&gt;
 &lt;br /&gt;
    if you have a vector of objects, you often want to track them individually outside the vector&lt;br /&gt;
    if you use a vector of pointers, you can move the object around much more cheaply, and not worry about costly large vector reallocations&lt;br /&gt;
    a vector of objects (not pointers) only makes sense if the number of objects is initially known and does not change over time&lt;br /&gt;
&lt;br /&gt;
    OBSERVATION THREE&lt;br /&gt;
 &lt;br /&gt;
    STL vectors can store your pointers, iterate thru them, etc.&lt;br /&gt;
    for a vector of any substantial size, you want to keep objects sorted so you can find them quickly&lt;br /&gt;
    that&#039;s what my sorted_vector class is for; it simply bolts vector together with sort calls and a b_sorted status&lt;br /&gt;
    following STL practices, to get sorting, you have to provide operator&amp;lt; for whatever is in your vector&lt;br /&gt;
    BUT... you are not allowed to do operator&amp;lt;(const MyObjectPtr* right) because it would require a reference to a pointer which is not allowed&lt;br /&gt;
    BUT... you can provide a FUNCTOR to do the job, then provide it when sorting/searching&lt;br /&gt;
    a functor is basically a structure with a bool operator()(const MyObjectPtr* left, const MyObjectPtr* right)&lt;br /&gt;
&lt;br /&gt;
    OBSERVATION FOUR&lt;br /&gt;
 &lt;br /&gt;
    unordered_set works even better when combining frequent CRUD with frequent lookups&lt;br /&gt;
&lt;br /&gt;
    SUMMARY&lt;br /&gt;
    Dealing with tons of objects is par for the course in any significant app.&lt;br /&gt;
    Finding a needle in the haystack of those objects is also standard fare.&lt;br /&gt;
    Having multiple indices into those objects is also essential.&lt;br /&gt;
    Using unordered_set with object pointers and is very powerful.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ stl reverse iterator skeleton&lt;br /&gt;
|-&lt;br /&gt;
| From [http://www.sgi.com/tech/stl/ReverseIterator.html SGI]...&lt;br /&gt;
 reverse_iterator rfirst(V.end());&lt;br /&gt;
 reverse_iterator rlast(V.begin());&lt;br /&gt;
 &lt;br /&gt;
 while (rfirst != rlast) &lt;br /&gt;
 {&lt;br /&gt;
     cout &amp;lt;&amp;lt; *rfirst &amp;lt;&amp;lt; endl;&lt;br /&gt;
     ...&lt;br /&gt;
     rfirst++;&lt;br /&gt;
 }&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ stl reading a binary file into a string&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
    std::ifstream in(&amp;quot;my.zip&amp;quot;,std::ios::binary);&lt;br /&gt;
    if (!in)&lt;br /&gt;
    {&lt;br /&gt;
       std::cout &amp;lt;&amp;lt; &amp;quot;problem with file open&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
       return 0;&lt;br /&gt;
    }&lt;br /&gt;
    in.seekg(0,std::ios::end);&lt;br /&gt;
    unsigned long length = in.tellg();&lt;br /&gt;
    in.seekg(0,std::ios::beg);&lt;br /&gt;
  &lt;br /&gt;
    string str(length,0);&lt;br /&gt;
    std::copy( &lt;br /&gt;
        std::istreambuf_iterator&amp;lt; char &amp;gt;(in) ,&lt;br /&gt;
        std::istreambuf_iterator&amp;lt; char &amp;gt;() ,&lt;br /&gt;
        str.begin() &lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
For more, see [[Reading a binary file|c++ stl reading a binary file]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C/C++ best-in-class tool selection&lt;br /&gt;
|- &lt;br /&gt;
| I need to have easy setup of debug-level tool support for portable C++11 code.  And I need to decide and stick to it to be efficient.&lt;br /&gt;
* &#039;&#039;&#039;Compiler selection&#039;&#039;&#039;&lt;br /&gt;
** linux and mac: gcc&lt;br /&gt;
** windows: Visual Studio&lt;br /&gt;
* &#039;&#039;&#039;IDE selection&#039;&#039;&#039;&lt;br /&gt;
** linux and mac: Qt Creator&lt;br /&gt;
** windows: Qt Creator (OR Visual Studio OR eclipse?)&lt;br /&gt;
* &#039;&#039;&#039;Debugger selection&#039;&#039;&#039;&lt;br /&gt;
** linux and mac: Qt Creator&lt;br /&gt;
** windows: Qt Creator (OR Visual Studio OR eclipse?)&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 include base constructor (etc) in derived class&lt;br /&gt;
|-&lt;br /&gt;
| The awesome C++11 way to steal the constructor from the base class, oh man I&#039;ve been waiting for this one...&lt;br /&gt;
  class HttpsServer : public Server&amp;lt;HTTPS&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    // DOES THIS FOR YOU!&lt;br /&gt;
    /*&lt;br /&gt;
    HttpsServer(unsigned short port, size_t num_threads, const std::string&amp;amp; cert_file, const std::string&amp;amp; private_key_file)&lt;br /&gt;
    :&lt;br /&gt;
        // Call base class&lt;br /&gt;
        Server&amp;lt;HTTPS&amp;gt;::Server(port, num_threads, cert_file, private_key_file)&lt;br /&gt;
    {}&lt;br /&gt;
    */&lt;br /&gt;
    using Server&amp;lt;HTTPS&amp;gt;::Server;&lt;br /&gt;
    ....&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 containers&lt;br /&gt;
|-&lt;br /&gt;
| sorted_vector || use when doing lots of unsorted insertions and maintaining constant sort would be expensive; vector is good for a big pile of things that only occasionally needs a sorted lookup&lt;br /&gt;
|-&lt;br /&gt;
| map || sorted binary search tree; always sorted by key; you can walk through in sorted order (choose unordered if not needed!)&lt;br /&gt;
|-&lt;br /&gt;
| multimap || same as map but allows dupe keys (not as common)&lt;br /&gt;
|-&lt;br /&gt;
| unordered_map || hashmap; always sorted by key; additional bucket required for hash collisions; no defined order when walking through&lt;br /&gt;
|-&lt;br /&gt;
| unordered_multimap || same as map but allows dupe keys; dupes are obviously in the same bucket, and you can walk just the dupes if needed&lt;br /&gt;
|-&lt;br /&gt;
| set&amp;lt;br&amp;gt;multiset&amp;lt;br&amp;gt;unordered_set&amp;lt;br&amp;gt;unordered_multiset || sets are just like maps, except the key is embedded in the object, nice for encapsulation.&amp;lt;br /&amp;gt;&lt;br /&gt;
Items must be const (!) since they are the key - sounds bad, but this is mitigated by the mutable keyword.&amp;lt;br /&amp;gt;&lt;br /&gt;
You can use mutable on the variables that are not part of the key to remove the const.&amp;lt;br /&amp;gt;&lt;br /&gt;
This changes the constness of the object from binary (completely const) to logical (constness is defined by the developer).&amp;lt;br /&amp;gt;&lt;br /&gt;
So... set is a good way to achieve both encapsulation and logical const - make const work for you, not against!  :-)&amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| set (etc.) of pointers || sets of pointers are the pinnacle of object stores&amp;lt;br /&amp;gt;&lt;br /&gt;
The entire object can be dereferenced and accessed then without const issues.&amp;lt;br /&amp;gt;&lt;br /&gt;
A pointer functor can be provided that does a sort by dereferencing the pointer to the object.&amp;lt;br /&amp;gt;&lt;br /&gt;
Two requirements: you must make sure yourself that you do not change the key values - you can mark them const, provided in constructor;&amp;lt;br /&amp;gt;&lt;br /&gt;
you must create sort/equal/hash functors that dereference the pointers to use object contents&amp;lt;br /&amp;gt;&lt;br /&gt;
(the default will be by pointer address).&amp;lt;br /&amp;gt;&lt;br /&gt;
The arguably biggest advantage, as a result, is that you can create multiple sets&amp;lt;br /&amp;gt;&lt;br /&gt;
to reference the same group of objects with different sort funtors to create multiple indices.&amp;lt;br /&amp;gt;&lt;br /&gt;
You just have to manage the keys carefully, so that they don&#039;t change (which would invalidate the sorting).&amp;lt;br /&amp;gt;&lt;br /&gt;
The primary container can manage object allocation; using a heap-based unique_ptr allocation&amp;lt;br /&amp;gt;&lt;br /&gt;
    map vs key redux&lt;br /&gt;
                &lt;br /&gt;
        use a key in the set, derive a class from it with the contents&lt;br /&gt;
            + small key&lt;br /&gt;
            + encapsulation&lt;br /&gt;
            - requires mutable to solve the const problem&lt;br /&gt;
        use a key in the set, key includes a mutable object&lt;br /&gt;
            + encapsulation&lt;br /&gt;
            - weird bc everything uses a const object but we have const functions like save() that change the mutable subobject&lt;br /&gt;
        use a map&lt;br /&gt;
            + small key&lt;br /&gt;
            - no encapsulation, have to deal with a pair instead of an object&lt;br /&gt;
                can we just put a ref to key in the value?  sure why not - err, bc we don&#039;t have access to it&lt;br /&gt;
            + solves const problem bc value is totally mutable by design&lt;br /&gt;
            + we can have multiple keys - and the value can have multiple refs to them&lt;br /&gt;
            + simpler equal and hash functions&lt;br /&gt;
        map:&lt;br /&gt;
            create an object with internal key(s)&lt;br /&gt;
            create map index(es) with duplicate key values outside the object - dupe data is the downside&lt;br /&gt;
        use set(s) with one static key for find(): &lt;br /&gt;
            create an object with internal key(s)&lt;br /&gt;
            create set index(es) with specific hash/equals functor(s)&lt;br /&gt;
            when finding, use one static key object (even across indexes!) so there isn&#039;t a big construction each time; just set the necessary key values&lt;br /&gt;
                that proves difficult when dealing with member vars that are references&lt;br /&gt;
                but to solve it, just set up a structure of dummy static key objects that use each other; then provide a function to setKey(Object&amp;amp; keyref) { keyref_ = keyref; }&lt;br /&gt;
                nope, can&#039;t reassign refs&lt;br /&gt;
                the solution: use pointers not references&lt;br /&gt;
                yes that&#039;s right&lt;br /&gt;
                just do it&lt;br /&gt;
                apparently there was a reason i was anti-reference for all those years&lt;br /&gt;
                two reasons to use pointers:&lt;br /&gt;
                    dynamically allocated&lt;br /&gt;
                    reassignment required&lt;br /&gt;
                there ya go.  simple.  get it done. &lt;br /&gt;
            when accessing find results from the set, use a const_cast on the object!&lt;br /&gt;
            WARNING: a separate base class with the key sounds good... but fails when you have more than one index on the object.  just use a static key object for them all!&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example for large groups of objects with frequent crud AND search&lt;br /&gt;
|-&lt;br /&gt;
| Best solution is an unordered set of pointers:&lt;br /&gt;
 typedef boost::unordered_set&amp;lt;MajorObject*&amp;gt; MajorObjects;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example for large groups of objects with infrequent crud and frequent search&lt;br /&gt;
|-&lt;br /&gt;
| Best solution is a vector of pointers sorted on demand (sorted_vector):&lt;br /&gt;
 TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example to associate two complex objects (one the map key, one the map value)&lt;br /&gt;
|-&lt;br /&gt;
| Use unordered_map with a custom object as key.  You must add hash and equals functions.  Boost makes it easy:&lt;br /&gt;
 static bool operator==(MyKeyObject const&amp;amp; m1, MyKeyObject const&amp;amp; m2)&lt;br /&gt;
 {&lt;br /&gt;
     return &lt;br /&gt;
             m1.id_0 == m2.id_0&lt;br /&gt;
         &amp;amp;&amp;amp;  m1.id_1 == m2.id_1;&lt;br /&gt;
 }&lt;br /&gt;
 static std::size_t hash_value(MyKeyObject const&amp;amp; mko)&lt;br /&gt;
 {&lt;br /&gt;
     std::size_t seed = 0;&lt;br /&gt;
     boost::hash_combine(seed, mko.id_0);&lt;br /&gt;
     boost::hash_combine(seed, mko.id_1);&lt;br /&gt;
     return seed;&lt;br /&gt;
 }&lt;br /&gt;
 typedef boost::unordered_map&amp;lt;MyKeyObject, MyValueObject*&amp;gt; MyMap;&lt;br /&gt;
Note that you can extend this to use a pointer to a key object, whoop.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example for multiple unordered_set indexes into one group of objects&lt;br /&gt;
|-&lt;br /&gt;
| Objects will be dynamically created.  One set should include them all and be responsible for memory allocation cleanup:&lt;br /&gt;
 TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example for set with specific sorting&lt;br /&gt;
|-&lt;br /&gt;
| Use set with a specific sort functor.  You can create as many of these indexes as you want!&lt;br /&gt;
 struct customers_set_sort_functor&lt;br /&gt;
 {&lt;br /&gt;
     bool operator()(const MyObject* l, const MyObject* r) const&lt;br /&gt;
     {&lt;br /&gt;
         // the id is the key&lt;br /&gt;
         return l-&amp;gt;id_ &amp;lt; r-&amp;gt;id_;&lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
 typedef set&amp;lt;MyObject*,myobject_sort_by_id_functor&amp;gt; MyObjectsById;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 loop through vector to erase some items&lt;br /&gt;
|-&lt;br /&gt;
| Note that other containers&#039; iterators may not be invalidated so you can just erase() as needed...&lt;br /&gt;
For vectors, you have to play with iterators to get it right - watch for proper ++ pre/postfix!&lt;br /&gt;
 for (it = numbers.begin(); it != numbers.end(); )  // NOTE we increment below, only if we don&#039;t erase&lt;br /&gt;
 {&lt;br /&gt;
     if (*it.no_good()) &lt;br /&gt;
     {&lt;br /&gt;
         numbers.erase(it++);  // NOTE that we ERASE THEN INCREMENT here.&lt;br /&gt;
     }&lt;br /&gt;
     else &lt;br /&gt;
     {&lt;br /&gt;
         ++it;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
I thought I had always looped backwards to do this, I *think* that&#039;s ok too, but I don&#039;t see it used in my code, I think I&#039;ll avoid.  :-)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 range based for loop, jacked with boost index if needed&lt;br /&gt;
|-&lt;br /&gt;
| No iterator usage at all.  Nice at times, not enough at others.  Make SURE to always use a reference or you will be working on a COPY.  Make it const if you aren&#039;t changing the object.&lt;br /&gt;
 for (auto&amp;amp; mc : my_container)&lt;br /&gt;
     mc.setString(&amp;quot;default&amp;quot;);&lt;br /&gt;
 for (const auto&amp;amp; cmc : my_container)&lt;br /&gt;
     cout &amp;lt;&amp;lt; cmc.asString();&lt;br /&gt;
boost index can give you the index if you need it, sweet:&lt;br /&gt;
 #include &amp;lt;boost/range/adaptor/indexed.hpp&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 for (const auto &amp;amp;element: boost::adaptors::index(mah_container))&lt;br /&gt;
     cout &amp;lt;&amp;lt; element.value() &amp;lt;&amp;lt; element.index();&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 for loop using lambda&lt;br /&gt;
|-&lt;br /&gt;
| This C++11 for loop is clean and elegant and a perfect way to check if your compiler is ready for c++11:&lt;br /&gt;
 vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
 for_each( v.begin(), v.end(), [] (int val)&lt;br /&gt;
 {&lt;br /&gt;
    cout &amp;lt;&amp;lt; val;&lt;br /&gt;
 } );&lt;br /&gt;
This is using a lambda function, we should switch from iterators and functors to those - but not quite yet, since we&#039;re writing cross-platform code.  Do not touch this until we can be sure that all platforms provide compatible C++11 handling.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 integer types&lt;br /&gt;
|-&lt;br /&gt;
| I really like the &amp;quot;fast&amp;quot; C++11 types, that give best performance for a guaranteed minimum bit width.  &lt;br /&gt;
Use them when you know a variable will not exceed the maximum value of that bit width, but does not have to be a precise bit width in memory or elsewhere.&lt;br /&gt;
&lt;br /&gt;
Pick specific-width fields whenever data is shared with other processes and components and you want a guarantee of its bit width.&lt;br /&gt;
&lt;br /&gt;
And when using pointer size and array indices you should use types defined for those specific situations.&lt;br /&gt;
&lt;br /&gt;
FAST types:&lt;br /&gt;
    int_fast8_t&lt;br /&gt;
    int_fast16_t                fastest signed integer type with width of&lt;br /&gt;
    int_fast32_t                at least 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    int_fast64_t&lt;br /&gt;
&lt;br /&gt;
    uint_fast8_t&lt;br /&gt;
    uint_fast16_t               fastest unsigned integer type with width of&lt;br /&gt;
    uint_fast32_t               at least 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    uint_fast64_t&lt;br /&gt;
SMALL types:&lt;br /&gt;
    int_least8_t&lt;br /&gt;
    int_least16_t               smallest signed integer type with width of&lt;br /&gt;
    int_least32_t               at least 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    int_least64_t&lt;br /&gt;
&lt;br /&gt;
    uint_least8_t&lt;br /&gt;
    uint_least16_t		smallest unsigned integer type with width of&lt;br /&gt;
    uint_least32_t		at least 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    uint_least64_t&lt;br /&gt;
EXACT types:&lt;br /&gt;
    int8_t                      signed integer type with width of&lt;br /&gt;
    int16_t                     exactly 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    int32_t                     with no padding bits and using 2&#039;s complement for negative values&lt;br /&gt;
    int64_t                     (provided only if the implementation directly supports the type)&lt;br /&gt;
&lt;br /&gt;
    uint8_t                     unsigned integer type with width of&lt;br /&gt;
    uint16_t                    exactly 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    uint32_t                    (provided only if the implementation directly supports the type)&lt;br /&gt;
    uint64_t&lt;br /&gt;
SPECIFIC-USE types:&lt;br /&gt;
    intptr_t                    integer type capable of holding a pointer&lt;br /&gt;
    uintptr_t                   unsigned integer type capable of holding a pointer &lt;br /&gt;
    size_t                      unsigned integer type capable of holding an array index (same size as uintptr_t)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C++11 scoped enumeration&lt;br /&gt;
|- &lt;br /&gt;
| C++11 has scoped enumeration, which lets you specify the SPECIFIC VARIABLE TYPE for the enum.  Perfect, let&#039;s use uint_fast32_t.&lt;br /&gt;
 enum class STRING_PREF_INDEX int_fast32_t: { ... };&lt;br /&gt;
Unfortunately, gcc gives me a scary warning, and stuff fails.  For some reason, it does not know about the provided type, although it is definitely defined.  Revisit this later if you have time.&lt;br /&gt;
 warning: elaborated-type-specifier for a scoped enum must not use the ‘class’ keyword&lt;br /&gt;
Old skool is still cool:&lt;br /&gt;
 typedef enum&lt;br /&gt;
 {&lt;br /&gt;
     // assert( SP_COUNT == 2 );&lt;br /&gt;
     SP_FIRST = 0                ,&lt;br /&gt;
     SP_SOME_PREF = SP_FIRST     ,&lt;br /&gt;
     SP_ANOTHA                   ,&lt;br /&gt;
 &lt;br /&gt;
     SP_COUNT&lt;br /&gt;
 } STRING_PREF_INDEX;&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! boost&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! boost release and debug build for linux&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
    # download latest boost, eg: boost_1_59_0 &lt;br /&gt;
    m@wallee:~/development$ 7z x boost_1_59_0.7z&lt;br /&gt;
    rm boost &amp;amp;&amp;amp; ln -s boost_1_59 boost&lt;br /&gt;
    cd boost&lt;br /&gt;
    build_boost_release_and_debug.sh&lt;br /&gt;
    # IMPORTANT: then patch .bashrc as instructed&lt;br /&gt;
    #     cmake-###/clean.sh and cmake-###/build.sh are customized to match&lt;br /&gt;
    #     (and older eclipse and server/nix/bootstrap.sh) &lt;br /&gt;
To upgrade a CMake project:&lt;br /&gt;
    cd cmake-###/&lt;br /&gt;
    ./clean.sh&lt;br /&gt;
    ./build.sh&lt;br /&gt;
To upgrade an older autotools project:&lt;br /&gt;
    cd nix&lt;br /&gt;
    make distclean  # removes nasty .deps folders that link to old boost if you let them&lt;br /&gt;
    make clean      # removes .o files etc&lt;br /&gt;
    cd ../build-Release &amp;amp;&amp;amp; make distclean &amp;amp;&amp;amp; make clean&lt;br /&gt;
    cd ../build-Debug &amp;amp;&amp;amp; make distclean &amp;amp;&amp;amp; make clean&lt;br /&gt;
    cd ..&lt;br /&gt;
    ./bootstrap force release&lt;br /&gt;
    ./bootstrap force debug&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! boost release and debug build for Windows&lt;br /&gt;
|-&lt;br /&gt;
| Open a VS2015 x64 Native Tools Command Prompt.  &lt;br /&gt;
EITHER: for new installs, you have to run bootstrap.bat first, it will build b2; &lt;br /&gt;
OR: for reruns, remove boost dirs: [bin.v2, stage].&lt;br /&gt;
Then build 64-bit:&lt;br /&gt;
 cd &amp;quot;....\boost_1_59_0&amp;quot;&lt;br /&gt;
 b2 toolset=msvc variant=release,debug link=static address-model=64&lt;br /&gt;
 rem trying to avoid excessive options, assuming I don&#039;t need these: threading=multi&lt;br /&gt;
 (old stuff)&lt;br /&gt;
       --toolset=msvc-14.0 address-model=64 --build-type=complete --stagedir=windows_lib\x64 stage&lt;br /&gt;
       Now open VS2013 x86 Native Tools Command Prompt and build 32-bit:&lt;br /&gt;
       cd &amp;quot;C:\Michael&#039;s Data\development\sixth_column\boost_1_55_0&amp;quot;&lt;br /&gt;
       bjam --toolset=msvc-12.0 address-model=32 --build-type=complete --stagedir=windows_lib\x86 stage&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! boost regex (very similar to c++11, with LESS BUGS and MORE POWER)&lt;br /&gt;
|-&lt;br /&gt;
| boost regex does everything you could need, take your time to get it right&lt;br /&gt;
* regex_search will work hard to find substrings, while regex_match requires your regex to match entire input&lt;br /&gt;
* smatch is a great way to get back a bunch of iterators to the results&lt;br /&gt;
example:&lt;br /&gt;
    virtual bool url_upgrade_any_old_semver(string&amp;amp; url)&lt;br /&gt;
    {&lt;br /&gt;
      // Perform a regex to update the embedded version if needed.&lt;br /&gt;
      // We have to see if (1) we have a semver and (2) it is not the current semver.&lt;br /&gt;
      // Only then do we take action.&lt;br /&gt;
      boost::regex regex(&amp;quot;/([v0-9.]+?)/(.*)&amp;quot;);&lt;br /&gt;
      boost::smatch sm_res;&lt;br /&gt;
      if (boost::regex_match(url,sm_res,regex,boost::match_default))&lt;br /&gt;
      {&lt;br /&gt;
        string incoming_semver(sm_res[1].first,sm_res[1].second);&lt;br /&gt;
        if (incoming_semver != semanticVersion())&lt;br /&gt;
        {&lt;br /&gt;
          url = string(&amp;quot;/&amp;quot;)+semanticVersion()+&amp;quot;/&amp;quot;+string(sm_res[2].first,sm_res[2].second);&lt;br /&gt;
          return true;&lt;br /&gt;
        }      &lt;br /&gt;
      }&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
results:&lt;br /&gt;
      original string:    string(sm_res[0].first,sm_res[0].second);&lt;br /&gt;
      first group:        string(sm_res[1].first,sm_res[1].second);&lt;br /&gt;
      second group:       string(sm_res[2].first,sm_res[2].second);&lt;br /&gt;
      etc.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C++ libraries&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! String escape formatting across different languages and systems&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* c++ to JSON: always use nlohmann::json j.dump() to encode, to ensure strings are properly escaped&lt;br /&gt;
* JSON to c++: always use nlohmann::json j.parse() &amp;quot;&lt;br /&gt;
* c++ to Javascript: use raw_to_Javascript() to properly escape&lt;br /&gt;
* c++ to sqlite: use SqliteLocalModel::safestr(), which uses double_doublequotes(str)&lt;br /&gt;
|}&lt;br /&gt;
[[Postgres]]&lt;br /&gt;
&lt;br /&gt;
[[Simple-Web-Server]]&lt;br /&gt;
&lt;br /&gt;
[[Robot Operating System]]&lt;br /&gt;
&lt;br /&gt;
[[C++ https libraries]]&lt;br /&gt;
&lt;br /&gt;
[[Configure Qt development on Windows + Mac + linux]]&lt;br /&gt;
&lt;br /&gt;
[[Build the TagLib library with Visual Studio 2013]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C/C++ building/linking&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gcc makefile pain&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* I went through a LOT of pain to determine that gcc requires libraries to be listed AFTER the source and output parameters&lt;br /&gt;
* set LD_LIBRARY_PATH to point to your libs if they are not in system location&lt;br /&gt;
* Make sure Makefile uses TABS NOT SPACES.  it&#039;s a FACT OF LIFE.  hate it if you want.  plenty more things to hate about linux/C as well.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gcc install multiple versions in ubuntu (4 and 5 in wily, eg)&lt;br /&gt;
|-&lt;br /&gt;
| My code will not compile with gcc 5, the version provided with Ubuntu wily.&lt;br /&gt;
It gives warnings like this:&lt;br /&gt;
 /home/m/development/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:547:34: warning: ‘template&amp;lt;class&amp;gt; class std::auto_ptr’ is deprecated [-Wdeprecated-declarations]&lt;br /&gt;
and outright errors like this:&lt;br /&gt;
 depbase=`echo AtServer.o | sed &#039;s|[^/]*$|.deps/&amp;amp;|;s|\.o$||&#039;`;\&lt;br /&gt;
 g++ -DPACKAGE_NAME=\&amp;quot;at_server\&amp;quot; -DPACKAGE_TARNAME=\&amp;quot;at_server\&amp;quot; -DPACKAGE_VERSION=\&amp;quot;1.0\&amp;quot; -DPACKAGE_STRING=\&amp;quot;at_server\ 1.0\&amp;quot; -DPACKAGE_BUGREPORT=\&amp;quot;m@abettersoftware.com\&amp;quot; -DPACKAGE_URL=\&amp;quot;\&amp;quot; -DPACKAGE=\&amp;quot;at_server\&amp;quot; -DVERSION=\&amp;quot;1.0\&amp;quot; -I. -I../../src  -I/home/m/development/Reusable/c++ -I/home/m/development/Reusable/c++/sqlite -std=c++11 -I/home/m/development/boost_1_59_0  -ggdb3 -O0 -std=c++11 -MT AtServer.o -MD -MP -MF $depbase.Tpo -c -o AtServer.o ../../src/AtServer.cpp &amp;amp;&amp;amp;\&lt;br /&gt;
 mv -f $depbase.Tpo $depbase.Po&lt;br /&gt;
 In file included from /usr/include/c++/5/bits/stl_algo.h:60:0,&lt;br /&gt;
                 from /usr/include/c++/5/algorithm:62,&lt;br /&gt;
                 from /usr/include/c++/5/ext/slist:47,&lt;br /&gt;
                 from /home/m/development/boost_1_59_0/boost/algorithm/string/std/slist_traits.hpp:16,&lt;br /&gt;
                 from /home/m/development/boost_1_59_0/boost/algorithm/string/std_containers_traits.hpp:23,&lt;br /&gt;
                 from /home/m/development/boost_1_59_0/boost/algorithm/string.hpp:18,&lt;br /&gt;
                 from /home/m/development/Reusable/c++/utilities.hpp:4,&lt;br /&gt;
                 from ../../src/MemoryModel.hpp:11,&lt;br /&gt;
                 from ../../src/SqliteLocalModel.hpp:13,&lt;br /&gt;
                 from ../../src/AtServer.cpp:70:&lt;br /&gt;
 /usr/include/c++/5/bits/algorithmfwd.h:573:13: error: initializer provided for function&lt;br /&gt;
     noexcept(__and_&amp;lt;is_nothrow_move_constructible&amp;lt;_Tp&amp;gt;,&lt;br /&gt;
             ^&lt;br /&gt;
 /usr/include/c++/5/bits/algorithmfwd.h:582:13: error: initializer provided for function&lt;br /&gt;
     noexcept(noexcept(swap(*__a, *__b)))&lt;br /&gt;
&lt;br /&gt;
You can set up the update-alternatives tool to switch out the symlinks:&lt;br /&gt;
 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9&lt;br /&gt;
 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 20 --slave /usr/bin/g++ g++ /usr/bin/g++-5&lt;br /&gt;
BUT that seems BAD to me to switch out the compiler used by the SYSTEM.  Instead, we should specify the compiler required by the PROJECT.  This is supposed to do it, but it still uses /usr/include/c++/5, which seems wrong, and gives me errors:&lt;br /&gt;
 CC=gcc-4.9&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[git]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Debugging&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Chrome capture large JSON variable&lt;br /&gt;
|- &lt;br /&gt;
| This is just pointlessly bizarre:&lt;br /&gt;
* hit a breakpoint in the chrome debugger&lt;br /&gt;
* right-click a variable and say &amp;quot;copy to global variable&amp;quot; (console will show name, typically &amp;quot;temp1&amp;quot;)&lt;br /&gt;
* push the variable to the clipboard by typing this in the console:&lt;br /&gt;
 copy(temp1)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Visual Studio Code capture large string variable&lt;br /&gt;
|- &lt;br /&gt;
| While debugging, you can use the Debug Console to print memory, including the content of strings that are clipped by default in the variables and watch windows.&lt;br /&gt;
 View &amp;gt; Open View &amp;gt; Debug Console&lt;br /&gt;
From there, send gdb a command to print memory – 300 characters of a string in this example:&lt;br /&gt;
 -exec x/300sb Query.c_str()&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Qt Creator conditional breakpoint&lt;br /&gt;
|-&lt;br /&gt;
| To break on line number with string condition:&lt;br /&gt;
* Set the breakpoint on the line as usual: F9 or click in left border&lt;br /&gt;
* In the breakpoints list, rclick Edit&lt;br /&gt;
* Add a condition; to break on a string value, THIS WORKS:&lt;br /&gt;
       &lt;br /&gt;
          ((int)strcmp(strSymbol.c_str(), &amp;quot;GMO&amp;quot;)) == 0&lt;br /&gt;
      &lt;br /&gt;
* BUT THERE IS A PRICE TO PAY.  qt/gcc won&#039;t continue properly, unless you sset ANOTHER common breakpoint, hit it, and resume from that.  It appears gcc continues (we hit the breakpoint after all), but qt does no logging or debugging, bah&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Qt Creator and linux debug libraries&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* I was able to build lws in debug, install in /usr/local, then I could step right into its code&lt;br /&gt;
 m@case:~/development/causam/git/np/nop-bigress-client-c$ ./build_lws_debug&lt;br /&gt;
  Install the project...&lt;br /&gt;
  -- Install configuration: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
  -- Installing: /usr/local/lib/pkgconfig/libwebsockets.pc&lt;br /&gt;
  -- Installing: /usr/local/lib/libwebsockets.a&lt;br /&gt;
  -- Up-to-date: /usr/local/include/libwebsockets.h&lt;br /&gt;
  (etc)&lt;br /&gt;
* Signals: At some point I needed to force gdb to pass SIGINT, SIGPIPE... signals to the app instead of gdb, after ssl kept causing Qt to pop a message and break in the debugger.  To do so:&lt;br /&gt;
        Qt Creator-&amp;gt;Options-&amp;gt;Debugger-&amp;gt;&lt;br /&gt;
            [ ] Show a message box when receiving a signal&lt;br /&gt;
            Debugger Helper Customization: handle SIGPIPE pass nostop noprint&lt;br /&gt;
* You should be able to install debug builds of libraries into /usr/local (as mentioned above).  Older notes if you can&#039;t get that going:  To debug into an included library that is not installed system-wide:&lt;br /&gt;
 use Tools-&amp;gt;Options-&amp;gt;General-&amp;gt;Source Paths Map&lt;br /&gt;
  source: /home/m/development/causam/git/nop-bigress-client-c/cmake-debug&lt;br /&gt;
    that&#039;s the COMPLETE PATH TO DEBUG EXE&lt;br /&gt;
  target: /home/m/development/causam/git/libwebsockets-master/lib&lt;br /&gt;
    at first i thought this would work: /usr/local/lib&lt;br /&gt;
    but i did a static build so i needed teh actual exe!  COOL&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! QT Creator valgrind EASY&lt;br /&gt;
|- &lt;br /&gt;
| Valgrind is easy to use.  Just find debugger pane top-left dropdown, switch mode from Debugger to Memcheck, and restart debugger.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c/c++ gdb debugging&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
 (gdb) help break&lt;br /&gt;
 Set breakpoint at specified line or function.&lt;br /&gt;
 Argument may be line number, function name, or &amp;quot;*&amp;quot; and an address.&lt;br /&gt;
 If line number is specified, break at start of code for that line.&lt;br /&gt;
 If function is specified, break at start of code for that function.&lt;br /&gt;
 If an address is specified, break at that exact address.&lt;br /&gt;
 With no arg, uses current execution address of selected stack frame.&lt;br /&gt;
 This is useful for breaking on return to a stack frame.&lt;br /&gt;
 &lt;br /&gt;
 Multiple breakpoints at one place are permitted, and useful if conditional.    &lt;br /&gt;
 &lt;br /&gt;
 Do &amp;quot;help breakpoints&amp;quot; for info on other commands dealing with breakpoints.&lt;br /&gt;
|- 		&lt;br /&gt;
| ddd gives you a front end.  I need to use it more, compare to other options&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Library handling in linux&lt;br /&gt;
|-&lt;br /&gt;
| gcc library basics (good to know for autotools and CMake too)&lt;br /&gt;
* The gcc -l command line option specifies a specific library NAME.  It will add the rest to give you (eg) lib[NAME].a&lt;br /&gt;
* Specify the library search path with the -L option.  Things that you as a user install seem to default to /usr/local/lib&lt;br /&gt;
* This will link myprogram with the static library libfoo.a in the folder /home/me/foo/lib.&lt;br /&gt;
        gcc -o myprogram -lfoo -L/home/me/foo/lib myprogram.c&lt;br /&gt;
Tools to check library dependencies:&lt;br /&gt;
* ldd [executable]&lt;br /&gt;
* objdump -p /path/to/program | grep NEEDED&lt;br /&gt;
* objdump -x [object.so]&lt;br /&gt;
* readelf -d [exe]&lt;br /&gt;
* sudo pldd &amp;lt;PID&amp;gt;&lt;br /&gt;
* sudo pmap &amp;lt;PID&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Cross Compiling]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C - Create a portable command line C project in Visual Studio &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
    Visual Studio: File -&amp;gt; New -&amp;gt; project&lt;br /&gt;
    Visual C++ -&amp;gt; Win32 -&amp;gt; Win32 Console Application&lt;br /&gt;
    name: oms_with_emap&lt;br /&gt;
    next -&amp;gt; click OFF precompiled header checkbox (even tho it didn&#039;t seem to respect it)&lt;br /&gt;
    you&#039;ll get a _tmain(..., TCHAR*...)&lt;br /&gt;
    change it to main(..., char*...)&lt;br /&gt;
    change the project to explicitly say &amp;quot;Not using precompiled header&amp;quot;&lt;br /&gt;
    remove the f&#039;in stdafx.h&lt;br /&gt;
    recompile!  should be clean&lt;br /&gt;
    vs will recognize C files and compile accordingly&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Javascript]]&lt;br /&gt;
|}&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Node.js]]&lt;br /&gt;
|}&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[React]]&lt;br /&gt;
|}&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Vite]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[JSON]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[HTML]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[CSS]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! SQL&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Count records within a range&lt;br /&gt;
|-&lt;br /&gt;
| This groups records into ranges, sorts by them, and gives a count, sweet:&lt;br /&gt;
    select count(*), id/1000000 as groupid from AccountHistory group by groupid;&lt;br /&gt;
|}&lt;br /&gt;
[[postgres]] - [[sqlite]] - [[mysql]] - [[SQL Server]] - [[Robo 3T]] - [[DBeaver]] - [[pgadmin4]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Meteor]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Android]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Arduino]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Raspberry Pi]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[iOS]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[.NET Core]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Java]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Kotlin]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Maven]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Scala]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Python]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Go]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! PHP&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! php debugging&lt;br /&gt;
|-&lt;br /&gt;
| Tail these:&lt;br /&gt;
 tail -f /var/log/apache2/sitelogs/thedigitalage.org/ssl_error_log&lt;br /&gt;
 tail -f /var/log/ampache-tda/ampache.(today).log&lt;br /&gt;
|-&lt;br /&gt;
| This leads to too much noise, not needed...&lt;br /&gt;
 emacs /etc/php/apache2-php5.3/php.ini&lt;br /&gt;
   display_errors = On&lt;br /&gt;
 /etc/init.d/apache restart&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Bash basics]] but please prefer node or python :-)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! misc&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! SVN repo move across servers&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* use a tool like VisualSVN to stop SVN server&lt;br /&gt;
* copy the repo&#039;s entire svn server directory, eg: c:\svn\Software&lt;br /&gt;
* copy it into the new server under a unique name, eg: c:\svn\NewSoftware&lt;br /&gt;
* use a tool like VisualSVN to restart SVN server&lt;br /&gt;
You should now have the new code, accessible as usual from svn.&lt;br /&gt;
NOTE from Tom: If you move code around, make sure you tag it, then copy the tag, to preserve history (as opposed to directly moving the folder).  Weird but true.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! SQL Server 2008+ proper upsert using MERGE&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
        -- We need an &amp;quot;upsert&amp;quot;: if record exists, update it, otherwise insert.&lt;br /&gt;
        -- There are several options to do that.&lt;br /&gt;
        -- Trying to do it correctly means...&lt;br /&gt;
        --		1) use a lock or transaction to make the upsert atomic&lt;br /&gt;
        --		2) use the best-available operation to maximize performance&lt;br /&gt;
        -- SQL Server 2008 has MERGE which may be slightly more efficient than &lt;br /&gt;
        -- separate check &amp;amp;&amp;amp; (insert||update) steps.  And we can do it with&lt;br /&gt;
        -- a single lock instead of a full transaction (which may be better?).&lt;br /&gt;
        -- It&#039;s messy to code up though since three blocks of fields must be specified.  &lt;br /&gt;
        -- Cest la vie.&lt;br /&gt;
        MERGE [dbo].[FACT_DCSR_RemPeriodMonthlyReport] WITH (HOLDLOCK) AS rpmr&lt;br /&gt;
        USING (SELECT @ID AS ID) AS new_foo&lt;br /&gt;
              ON rpmr.ID = new_foo.ID&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                @last_months_year as DCSRYear,&lt;br /&gt;
                @last_month as DCSRMonth,&lt;br /&gt;
                @last_month_name as MonthName,&lt;br /&gt;
                Device_Type_ID,&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
        WHEN MATCHED THEN&lt;br /&gt;
            UPDATE&lt;br /&gt;
                    SET f.UpdateSpid = @@SPID, &lt;br /&gt;
                    UpdateTime = SYSDATETIME() &lt;br /&gt;
        WHEN NOT MATCHED THEN&lt;br /&gt;
            INSERT&lt;br /&gt;
              (&lt;br /&gt;
                    ID, &lt;br /&gt;
                    InsertSpid, &lt;br /&gt;
                    InsertTime&lt;br /&gt;
              )&lt;br /&gt;
            VALUES&lt;br /&gt;
              (&lt;br /&gt;
                    new_foo.ID, &lt;br /&gt;
                    @@SPID, &lt;br /&gt;
                    SYSDATETIME()&lt;br /&gt;
              );&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Web Services]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Firefox Addon development]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ Create a portable autotools C++ project in linux&lt;br /&gt;
|-&lt;br /&gt;
| (OLD, USE CMAKE NOW)&lt;br /&gt;
&lt;br /&gt;
For anything serious, it&#039;s best to clone an existing project&#039;s skeleton.&lt;br /&gt;
* main.cpp&lt;br /&gt;
* MVC code&lt;br /&gt;
* nix/copy_from folder&lt;br /&gt;
* make sure .bashrc is configured for boost&lt;br /&gt;
* nix$  bootstrap_autotools_project.sh force release debug&lt;br /&gt;
* set up eclipse according to screenshots in [[Eclipse]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ Create a portable C++ project in Visual Studio &lt;br /&gt;
|-&lt;br /&gt;
| (OLD, USE CMAKE NOW)&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have existing code, it&#039;s probably best to create a project_name.cpp file with your main() function.&lt;br /&gt;
 int main( int argc, char * argv[] )&lt;br /&gt;
 { &lt;br /&gt;
     return 0;&lt;br /&gt;
 }&lt;br /&gt;
Then in Visual Studio...&lt;br /&gt;
 File-&amp;gt;New-&amp;gt;Project from existing code&lt;br /&gt;
 C++&lt;br /&gt;
 (then use mostly defaults on this page, once you provide file location and project name)&lt;br /&gt;
 Project file location:  &amp;lt;base&amp;gt;\project_name&lt;br /&gt;
 Project name: project_name&lt;br /&gt;
 [x] Add files from these folders&lt;br /&gt;
    Add subs  &lt;br /&gt;
    [x]        &amp;lt;base&amp;gt;\project_name&lt;br /&gt;
 NEXT&lt;br /&gt;
 Use Visual Studio&lt;br /&gt;
   Console application project&lt;br /&gt;
   No ATL, MFC, CLR&lt;br /&gt;
 NEXT&lt;br /&gt;
 NEXT&lt;br /&gt;
 FINISH&lt;br /&gt;
Then add Reusable and boost include and lib paths:&lt;br /&gt;
Example if you built boost according to notes below:&lt;br /&gt;
 Project-&amp;gt;Properties-&amp;gt;All Configurations-&amp;gt;Configuration Properties-&amp;gt;VC++ Directories-&amp;gt;Include Directories-&amp;gt;&lt;br /&gt;
    $(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\..\Reusable\c++&lt;br /&gt;
 INCLUDE: C:\Software Development\boost_1_53_0&lt;br /&gt;
 LIB: C:\Software Development\boost_1_53_0\stage\lib&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=AI&amp;diff=7909</id>
		<title>AI</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=AI&amp;diff=7909"/>
		<updated>2026-01-01T14:14:29Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[AI Coding]]&lt;br /&gt;
&lt;br /&gt;
[[AI Browser Prompts]]&lt;br /&gt;
&lt;br /&gt;
[[AI Mobile Apps]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=AI&amp;diff=7908</id>
		<title>AI</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=AI&amp;diff=7908"/>
		<updated>2026-01-01T14:13:56Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[AI Coding]]&lt;br /&gt;
&lt;br /&gt;
[[AI Prompts]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=AI&amp;diff=7907</id>
		<title>AI</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=AI&amp;diff=7907"/>
		<updated>2026-01-01T14:13:34Z</updated>

		<summary type="html">&lt;p&gt;M: Created page with &amp;quot;AI Coding&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[AI Coding]]&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Development_reference&amp;diff=7906</id>
		<title>Development reference</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Development_reference&amp;diff=7906"/>
		<updated>2026-01-01T14:13:13Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Design, programming and version control.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[AI]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Patterns&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Major Objects]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Quick-http]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Continuous Integration]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [http://www.aosabook.org/en/index.html Architecture of major open source apps]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Security]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Model View Controller]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! nosql enhances, not replaces, SQL&lt;br /&gt;
|-&lt;br /&gt;
| Not all data should be denormalized, and not all data should be normalized.  The optimal mix considers the extent of the data.  &lt;br /&gt;
&lt;br /&gt;
* Precise schemas are good when not overdone&lt;br /&gt;
* When a container has an array with a large number of elements, it should be normalized&lt;br /&gt;
* Sparse data and heterogeneous data are the best candidates for denormalization&lt;br /&gt;
&lt;br /&gt;
Postgres with JSON allows an elegant combination of nosql and SQL.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Web design mantra&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
# DESIGN INPUT TO THE INPUT DEVICE &lt;br /&gt;
## respect the input device&lt;br /&gt;
## detect it and use a reasonable default guess&lt;br /&gt;
## allow manual override&lt;br /&gt;
## [mouse/pen]...[finger]&lt;br /&gt;
##  sm-md-lg  ...  sm-md-lg&lt;br /&gt;
# DESIGN VISUALS TO THE SCREEN&lt;br /&gt;
## high-res = SHOW LOTS OF DETAIL&lt;br /&gt;
## responsive, zoomable&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! git central shared repository&lt;br /&gt;
|-&lt;br /&gt;
| Use bare repos for any central shared repositories.  Use the [####.git] suffix on bare repo names.&lt;br /&gt;
&lt;br /&gt;
Bare repositories are designed to be shared.  Maintenance on the central server is easier because you don&#039;t have local files to manage permissions or constant flux.  Plus, you can always have a second repo on the central server where you check out a specific branch (e.g. to serve up with apache).  If you want a dynamically updated central repo, clone the ###.git repo to ###, and add a post-receive hook (see bitpost quick-http.git for a good example).&lt;br /&gt;
&lt;br /&gt;
To configure the repo as shared:&lt;br /&gt;
 git config core.sharedRepository true&lt;br /&gt;
To set it on a new git repo during initial setup, make sure devs are in the same group, and use:&lt;br /&gt;
 git init --shared=group&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Occam&#039;s razor&lt;br /&gt;
|-&lt;br /&gt;
| Among competing hypotheses, the one with the fewest assumptions should be selected.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C++&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Deleting multiple elements in a collection&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* For sequences (vector, list...), best practice is to use the [https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom erase-remove] STL pattern&lt;br /&gt;
* For associative containers (set, map...): just recurse and remove iterators, they won&#039;t muck up the sequence.  [http://stackoverflow.com/questions/800955/remove-if-equivalent-for-stdmap example]&lt;br /&gt;
See MemoryModel::saveDirtyObjectsAsNeeded() for example code.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ Create a portable C/C++ project&lt;br /&gt;
|-&lt;br /&gt;
| Use QtCreator + CMake, both available everywhere!&lt;br /&gt;
    set up:&lt;br /&gt;
        create a Qt project as: New Project-&amp;gt; Non-Qt/Plain C Project (CMake Build)&lt;br /&gt;
            pick the PARENT and use the name of the existing folder&lt;br /&gt;
            set up a build folder in the existing folder, called (base)/qtcreator-release-build&lt;br /&gt;
            it creates CMakeLists.txt (THIS IS BASICALLY THE PROJECT FILE!)&lt;br /&gt;
            also creates main.c or something&lt;br /&gt;
            build it!  make sure it works&lt;br /&gt;
            NOW we can edit CMakeLists.txt - change . to ./src to get it to scan the src folder for code!&lt;br /&gt;
            and easily add &amp;quot;known&amp;quot; libs!  this was all i needed:&lt;br /&gt;
                TARGET_LINK_LIBRARIES(${PROJECT_NAME} pthread websockets)&lt;br /&gt;
            make sure it builds&lt;br /&gt;
            now we want a DEBUG build as well!&lt;br /&gt;
            Projects-&amp;gt;Build&amp;amp;Run-&amp;gt;pick Build in weird Build/Run pillbox-&amp;gt;Edit build configs:&lt;br /&gt;
                Rename: release&lt;br /&gt;
                CMake build dir: Make sure build dir is set to release ie qtcreator-debug-build&lt;br /&gt;
                Add: Clone: release, name: debug&lt;br /&gt;
                    for debug, add a custom build step BEFORE make step:&lt;br /&gt;
                        command: /usr/bin/cmake&lt;br /&gt;
                        args: -DCMAKE_BUILD_TYPE=Debug .&lt;br /&gt;
                        working dir: %{buildDir}&lt;br /&gt;
                        (add it, and move it up above make)&lt;br /&gt;
                        (build em both)&lt;br /&gt;
            Projects-&amp;gt;Build&amp;amp;Run-&amp;gt;pick Run in weird Build/Run pillbox&lt;br /&gt;
                Run Configuration: rename to &amp;quot;{...} release&amp;quot;&lt;br /&gt;
                clone it into &amp;quot;{...} debug&amp;quot;&lt;br /&gt;
                change working dir to match Build path&lt;br /&gt;
                change any needed params&lt;br /&gt;
    Now you should have build+run debug+release configurations, selectable in the weird project icon in bottom of left-side toolbar (&amp;quot;mode selector&amp;quot;)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ in-memory storage of &amp;quot;major&amp;quot; objects&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
    OBSERVATION ONE&lt;br /&gt;
 &lt;br /&gt;
    Consider An Important Qt Design: QObjects cannot normally be copied&lt;br /&gt;
        their copy constructors and assignment operators are private&lt;br /&gt;
        why?  A Qt Object...&lt;br /&gt;
            might have a unique QObject::objectName(). If we copy a Qt Object, what name should we give the copy?&lt;br /&gt;
            has a location in an object hierarchy. If we copy a Qt Object, where should the copy be located?&lt;br /&gt;
            can be connected to other Qt Objects to emit signals to them or to receive signals emitted by them. If we copy a Qt Object, how should we transfer these connections to the copy?&lt;br /&gt;
            can have new properties added to it at runtime that are not declared in the C++ class. If we copy a Qt Object, should the copy include the properties that were added to the original?&lt;br /&gt;
    in other words, a QObject is a pretty serious object that has the ability to be tied to other objects and resources in ways that make copying dangerous&lt;br /&gt;
    isn&#039;t this true of all serious objects?  pretty much&lt;br /&gt;
&lt;br /&gt;
    OBSERVATION TWO&lt;br /&gt;
 &lt;br /&gt;
    if you have a vector of objects, you often want to track them individually outside the vector&lt;br /&gt;
    if you use a vector of pointers, you can move the object around much more cheaply, and not worry about costly large vector reallocations&lt;br /&gt;
    a vector of objects (not pointers) only makes sense if the number of objects is initially known and does not change over time&lt;br /&gt;
&lt;br /&gt;
    OBSERVATION THREE&lt;br /&gt;
 &lt;br /&gt;
    STL vectors can store your pointers, iterate thru them, etc.&lt;br /&gt;
    for a vector of any substantial size, you want to keep objects sorted so you can find them quickly&lt;br /&gt;
    that&#039;s what my sorted_vector class is for; it simply bolts vector together with sort calls and a b_sorted status&lt;br /&gt;
    following STL practices, to get sorting, you have to provide operator&amp;lt; for whatever is in your vector&lt;br /&gt;
    BUT... you are not allowed to do operator&amp;lt;(const MyObjectPtr* right) because it would require a reference to a pointer which is not allowed&lt;br /&gt;
    BUT... you can provide a FUNCTOR to do the job, then provide it when sorting/searching&lt;br /&gt;
    a functor is basically a structure with a bool operator()(const MyObjectPtr* left, const MyObjectPtr* right)&lt;br /&gt;
&lt;br /&gt;
    OBSERVATION FOUR&lt;br /&gt;
 &lt;br /&gt;
    unordered_set works even better when combining frequent CRUD with frequent lookups&lt;br /&gt;
&lt;br /&gt;
    SUMMARY&lt;br /&gt;
    Dealing with tons of objects is par for the course in any significant app.&lt;br /&gt;
    Finding a needle in the haystack of those objects is also standard fare.&lt;br /&gt;
    Having multiple indices into those objects is also essential.&lt;br /&gt;
    Using unordered_set with object pointers and is very powerful.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ stl reverse iterator skeleton&lt;br /&gt;
|-&lt;br /&gt;
| From [http://www.sgi.com/tech/stl/ReverseIterator.html SGI]...&lt;br /&gt;
 reverse_iterator rfirst(V.end());&lt;br /&gt;
 reverse_iterator rlast(V.begin());&lt;br /&gt;
 &lt;br /&gt;
 while (rfirst != rlast) &lt;br /&gt;
 {&lt;br /&gt;
     cout &amp;lt;&amp;lt; *rfirst &amp;lt;&amp;lt; endl;&lt;br /&gt;
     ...&lt;br /&gt;
     rfirst++;&lt;br /&gt;
 }&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ stl reading a binary file into a string&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
    std::ifstream in(&amp;quot;my.zip&amp;quot;,std::ios::binary);&lt;br /&gt;
    if (!in)&lt;br /&gt;
    {&lt;br /&gt;
       std::cout &amp;lt;&amp;lt; &amp;quot;problem with file open&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
       return 0;&lt;br /&gt;
    }&lt;br /&gt;
    in.seekg(0,std::ios::end);&lt;br /&gt;
    unsigned long length = in.tellg();&lt;br /&gt;
    in.seekg(0,std::ios::beg);&lt;br /&gt;
  &lt;br /&gt;
    string str(length,0);&lt;br /&gt;
    std::copy( &lt;br /&gt;
        std::istreambuf_iterator&amp;lt; char &amp;gt;(in) ,&lt;br /&gt;
        std::istreambuf_iterator&amp;lt; char &amp;gt;() ,&lt;br /&gt;
        str.begin() &lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
For more, see [[Reading a binary file|c++ stl reading a binary file]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C/C++ best-in-class tool selection&lt;br /&gt;
|- &lt;br /&gt;
| I need to have easy setup of debug-level tool support for portable C++11 code.  And I need to decide and stick to it to be efficient.&lt;br /&gt;
* &#039;&#039;&#039;Compiler selection&#039;&#039;&#039;&lt;br /&gt;
** linux and mac: gcc&lt;br /&gt;
** windows: Visual Studio&lt;br /&gt;
* &#039;&#039;&#039;IDE selection&#039;&#039;&#039;&lt;br /&gt;
** linux and mac: Qt Creator&lt;br /&gt;
** windows: Qt Creator (OR Visual Studio OR eclipse?)&lt;br /&gt;
* &#039;&#039;&#039;Debugger selection&#039;&#039;&#039;&lt;br /&gt;
** linux and mac: Qt Creator&lt;br /&gt;
** windows: Qt Creator (OR Visual Studio OR eclipse?)&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 include base constructor (etc) in derived class&lt;br /&gt;
|-&lt;br /&gt;
| The awesome C++11 way to steal the constructor from the base class, oh man I&#039;ve been waiting for this one...&lt;br /&gt;
  class HttpsServer : public Server&amp;lt;HTTPS&amp;gt;&lt;br /&gt;
  {&lt;br /&gt;
    // DOES THIS FOR YOU!&lt;br /&gt;
    /*&lt;br /&gt;
    HttpsServer(unsigned short port, size_t num_threads, const std::string&amp;amp; cert_file, const std::string&amp;amp; private_key_file)&lt;br /&gt;
    :&lt;br /&gt;
        // Call base class&lt;br /&gt;
        Server&amp;lt;HTTPS&amp;gt;::Server(port, num_threads, cert_file, private_key_file)&lt;br /&gt;
    {}&lt;br /&gt;
    */&lt;br /&gt;
    using Server&amp;lt;HTTPS&amp;gt;::Server;&lt;br /&gt;
    ....&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 containers&lt;br /&gt;
|-&lt;br /&gt;
| sorted_vector || use when doing lots of unsorted insertions and maintaining constant sort would be expensive; vector is good for a big pile of things that only occasionally needs a sorted lookup&lt;br /&gt;
|-&lt;br /&gt;
| map || sorted binary search tree; always sorted by key; you can walk through in sorted order (choose unordered if not needed!)&lt;br /&gt;
|-&lt;br /&gt;
| multimap || same as map but allows dupe keys (not as common)&lt;br /&gt;
|-&lt;br /&gt;
| unordered_map || hashmap; always sorted by key; additional bucket required for hash collisions; no defined order when walking through&lt;br /&gt;
|-&lt;br /&gt;
| unordered_multimap || same as map but allows dupe keys; dupes are obviously in the same bucket, and you can walk just the dupes if needed&lt;br /&gt;
|-&lt;br /&gt;
| set&amp;lt;br&amp;gt;multiset&amp;lt;br&amp;gt;unordered_set&amp;lt;br&amp;gt;unordered_multiset || sets are just like maps, except the key is embedded in the object, nice for encapsulation.&amp;lt;br /&amp;gt;&lt;br /&gt;
Items must be const (!) since they are the key - sounds bad, but this is mitigated by the mutable keyword.&amp;lt;br /&amp;gt;&lt;br /&gt;
You can use mutable on the variables that are not part of the key to remove the const.&amp;lt;br /&amp;gt;&lt;br /&gt;
This changes the constness of the object from binary (completely const) to logical (constness is defined by the developer).&amp;lt;br /&amp;gt;&lt;br /&gt;
So... set is a good way to achieve both encapsulation and logical const - make const work for you, not against!  :-)&amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| set (etc.) of pointers || sets of pointers are the pinnacle of object stores&amp;lt;br /&amp;gt;&lt;br /&gt;
The entire object can be dereferenced and accessed then without const issues.&amp;lt;br /&amp;gt;&lt;br /&gt;
A pointer functor can be provided that does a sort by dereferencing the pointer to the object.&amp;lt;br /&amp;gt;&lt;br /&gt;
Two requirements: you must make sure yourself that you do not change the key values - you can mark them const, provided in constructor;&amp;lt;br /&amp;gt;&lt;br /&gt;
you must create sort/equal/hash functors that dereference the pointers to use object contents&amp;lt;br /&amp;gt;&lt;br /&gt;
(the default will be by pointer address).&amp;lt;br /&amp;gt;&lt;br /&gt;
The arguably biggest advantage, as a result, is that you can create multiple sets&amp;lt;br /&amp;gt;&lt;br /&gt;
to reference the same group of objects with different sort funtors to create multiple indices.&amp;lt;br /&amp;gt;&lt;br /&gt;
You just have to manage the keys carefully, so that they don&#039;t change (which would invalidate the sorting).&amp;lt;br /&amp;gt;&lt;br /&gt;
The primary container can manage object allocation; using a heap-based unique_ptr allocation&amp;lt;br /&amp;gt;&lt;br /&gt;
    map vs key redux&lt;br /&gt;
                &lt;br /&gt;
        use a key in the set, derive a class from it with the contents&lt;br /&gt;
            + small key&lt;br /&gt;
            + encapsulation&lt;br /&gt;
            - requires mutable to solve the const problem&lt;br /&gt;
        use a key in the set, key includes a mutable object&lt;br /&gt;
            + encapsulation&lt;br /&gt;
            - weird bc everything uses a const object but we have const functions like save() that change the mutable subobject&lt;br /&gt;
        use a map&lt;br /&gt;
            + small key&lt;br /&gt;
            - no encapsulation, have to deal with a pair instead of an object&lt;br /&gt;
                can we just put a ref to key in the value?  sure why not - err, bc we don&#039;t have access to it&lt;br /&gt;
            + solves const problem bc value is totally mutable by design&lt;br /&gt;
            + we can have multiple keys - and the value can have multiple refs to them&lt;br /&gt;
            + simpler equal and hash functions&lt;br /&gt;
        map:&lt;br /&gt;
            create an object with internal key(s)&lt;br /&gt;
            create map index(es) with duplicate key values outside the object - dupe data is the downside&lt;br /&gt;
        use set(s) with one static key for find(): &lt;br /&gt;
            create an object with internal key(s)&lt;br /&gt;
            create set index(es) with specific hash/equals functor(s)&lt;br /&gt;
            when finding, use one static key object (even across indexes!) so there isn&#039;t a big construction each time; just set the necessary key values&lt;br /&gt;
                that proves difficult when dealing with member vars that are references&lt;br /&gt;
                but to solve it, just set up a structure of dummy static key objects that use each other; then provide a function to setKey(Object&amp;amp; keyref) { keyref_ = keyref; }&lt;br /&gt;
                nope, can&#039;t reassign refs&lt;br /&gt;
                the solution: use pointers not references&lt;br /&gt;
                yes that&#039;s right&lt;br /&gt;
                just do it&lt;br /&gt;
                apparently there was a reason i was anti-reference for all those years&lt;br /&gt;
                two reasons to use pointers:&lt;br /&gt;
                    dynamically allocated&lt;br /&gt;
                    reassignment required&lt;br /&gt;
                there ya go.  simple.  get it done. &lt;br /&gt;
            when accessing find results from the set, use a const_cast on the object!&lt;br /&gt;
            WARNING: a separate base class with the key sounds good... but fails when you have more than one index on the object.  just use a static key object for them all!&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example for large groups of objects with frequent crud AND search&lt;br /&gt;
|-&lt;br /&gt;
| Best solution is an unordered set of pointers:&lt;br /&gt;
 typedef boost::unordered_set&amp;lt;MajorObject*&amp;gt; MajorObjects;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example for large groups of objects with infrequent crud and frequent search&lt;br /&gt;
|-&lt;br /&gt;
| Best solution is a vector of pointers sorted on demand (sorted_vector):&lt;br /&gt;
 TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example to associate two complex objects (one the map key, one the map value)&lt;br /&gt;
|-&lt;br /&gt;
| Use unordered_map with a custom object as key.  You must add hash and equals functions.  Boost makes it easy:&lt;br /&gt;
 static bool operator==(MyKeyObject const&amp;amp; m1, MyKeyObject const&amp;amp; m2)&lt;br /&gt;
 {&lt;br /&gt;
     return &lt;br /&gt;
             m1.id_0 == m2.id_0&lt;br /&gt;
         &amp;amp;&amp;amp;  m1.id_1 == m2.id_1;&lt;br /&gt;
 }&lt;br /&gt;
 static std::size_t hash_value(MyKeyObject const&amp;amp; mko)&lt;br /&gt;
 {&lt;br /&gt;
     std::size_t seed = 0;&lt;br /&gt;
     boost::hash_combine(seed, mko.id_0);&lt;br /&gt;
     boost::hash_combine(seed, mko.id_1);&lt;br /&gt;
     return seed;&lt;br /&gt;
 }&lt;br /&gt;
 typedef boost::unordered_map&amp;lt;MyKeyObject, MyValueObject*&amp;gt; MyMap;&lt;br /&gt;
Note that you can extend this to use a pointer to a key object, whoop.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example for multiple unordered_set indexes into one group of objects&lt;br /&gt;
|-&lt;br /&gt;
| Objects will be dynamically created.  One set should include them all and be responsible for memory allocation cleanup:&lt;br /&gt;
 TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 example for set with specific sorting&lt;br /&gt;
|-&lt;br /&gt;
| Use set with a specific sort functor.  You can create as many of these indexes as you want!&lt;br /&gt;
 struct customers_set_sort_functor&lt;br /&gt;
 {&lt;br /&gt;
     bool operator()(const MyObject* l, const MyObject* r) const&lt;br /&gt;
     {&lt;br /&gt;
         // the id is the key&lt;br /&gt;
         return l-&amp;gt;id_ &amp;lt; r-&amp;gt;id_;&lt;br /&gt;
     }&lt;br /&gt;
 };&lt;br /&gt;
 typedef set&amp;lt;MyObject*,myobject_sort_by_id_functor&amp;gt; MyObjectsById;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 loop through vector to erase some items&lt;br /&gt;
|-&lt;br /&gt;
| Note that other containers&#039; iterators may not be invalidated so you can just erase() as needed...&lt;br /&gt;
For vectors, you have to play with iterators to get it right - watch for proper ++ pre/postfix!&lt;br /&gt;
 for (it = numbers.begin(); it != numbers.end(); )  // NOTE we increment below, only if we don&#039;t erase&lt;br /&gt;
 {&lt;br /&gt;
     if (*it.no_good()) &lt;br /&gt;
     {&lt;br /&gt;
         numbers.erase(it++);  // NOTE that we ERASE THEN INCREMENT here.&lt;br /&gt;
     }&lt;br /&gt;
     else &lt;br /&gt;
     {&lt;br /&gt;
         ++it;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
I thought I had always looped backwards to do this, I *think* that&#039;s ok too, but I don&#039;t see it used in my code, I think I&#039;ll avoid.  :-)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 range based for loop, jacked with boost index if needed&lt;br /&gt;
|-&lt;br /&gt;
| No iterator usage at all.  Nice at times, not enough at others.  Make SURE to always use a reference or you will be working on a COPY.  Make it const if you aren&#039;t changing the object.&lt;br /&gt;
 for (auto&amp;amp; mc : my_container)&lt;br /&gt;
     mc.setString(&amp;quot;default&amp;quot;);&lt;br /&gt;
 for (const auto&amp;amp; cmc : my_container)&lt;br /&gt;
     cout &amp;lt;&amp;lt; cmc.asString();&lt;br /&gt;
boost index can give you the index if you need it, sweet:&lt;br /&gt;
 #include &amp;lt;boost/range/adaptor/indexed.hpp&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 for (const auto &amp;amp;element: boost::adaptors::index(mah_container))&lt;br /&gt;
     cout &amp;lt;&amp;lt; element.value() &amp;lt;&amp;lt; element.index();&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 for loop using lambda&lt;br /&gt;
|-&lt;br /&gt;
| This C++11 for loop is clean and elegant and a perfect way to check if your compiler is ready for c++11:&lt;br /&gt;
 vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
 for_each( v.begin(), v.end(), [] (int val)&lt;br /&gt;
 {&lt;br /&gt;
    cout &amp;lt;&amp;lt; val;&lt;br /&gt;
 } );&lt;br /&gt;
This is using a lambda function, we should switch from iterators and functors to those - but not quite yet, since we&#039;re writing cross-platform code.  Do not touch this until we can be sure that all platforms provide compatible C++11 handling.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++11 integer types&lt;br /&gt;
|-&lt;br /&gt;
| I really like the &amp;quot;fast&amp;quot; C++11 types, that give best performance for a guaranteed minimum bit width.  &lt;br /&gt;
Use them when you know a variable will not exceed the maximum value of that bit width, but does not have to be a precise bit width in memory or elsewhere.&lt;br /&gt;
&lt;br /&gt;
Pick specific-width fields whenever data is shared with other processes and components and you want a guarantee of its bit width.&lt;br /&gt;
&lt;br /&gt;
And when using pointer size and array indices you should use types defined for those specific situations.&lt;br /&gt;
&lt;br /&gt;
FAST types:&lt;br /&gt;
    int_fast8_t&lt;br /&gt;
    int_fast16_t                fastest signed integer type with width of&lt;br /&gt;
    int_fast32_t                at least 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    int_fast64_t&lt;br /&gt;
&lt;br /&gt;
    uint_fast8_t&lt;br /&gt;
    uint_fast16_t               fastest unsigned integer type with width of&lt;br /&gt;
    uint_fast32_t               at least 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    uint_fast64_t&lt;br /&gt;
SMALL types:&lt;br /&gt;
    int_least8_t&lt;br /&gt;
    int_least16_t               smallest signed integer type with width of&lt;br /&gt;
    int_least32_t               at least 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    int_least64_t&lt;br /&gt;
&lt;br /&gt;
    uint_least8_t&lt;br /&gt;
    uint_least16_t		smallest unsigned integer type with width of&lt;br /&gt;
    uint_least32_t		at least 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    uint_least64_t&lt;br /&gt;
EXACT types:&lt;br /&gt;
    int8_t                      signed integer type with width of&lt;br /&gt;
    int16_t                     exactly 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    int32_t                     with no padding bits and using 2&#039;s complement for negative values&lt;br /&gt;
    int64_t                     (provided only if the implementation directly supports the type)&lt;br /&gt;
&lt;br /&gt;
    uint8_t                     unsigned integer type with width of&lt;br /&gt;
    uint16_t                    exactly 8, 16, 32 and 64 bits respectively&lt;br /&gt;
    uint32_t                    (provided only if the implementation directly supports the type)&lt;br /&gt;
    uint64_t&lt;br /&gt;
SPECIFIC-USE types:&lt;br /&gt;
    intptr_t                    integer type capable of holding a pointer&lt;br /&gt;
    uintptr_t                   unsigned integer type capable of holding a pointer &lt;br /&gt;
    size_t                      unsigned integer type capable of holding an array index (same size as uintptr_t)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C++11 scoped enumeration&lt;br /&gt;
|- &lt;br /&gt;
| C++11 has scoped enumeration, which lets you specify the SPECIFIC VARIABLE TYPE for the enum.  Perfect, let&#039;s use uint_fast32_t.&lt;br /&gt;
 enum class STRING_PREF_INDEX int_fast32_t: { ... };&lt;br /&gt;
Unfortunately, gcc gives me a scary warning, and stuff fails.  For some reason, it does not know about the provided type, although it is definitely defined.  Revisit this later if you have time.&lt;br /&gt;
 warning: elaborated-type-specifier for a scoped enum must not use the ‘class’ keyword&lt;br /&gt;
Old skool is still cool:&lt;br /&gt;
 typedef enum&lt;br /&gt;
 {&lt;br /&gt;
     // assert( SP_COUNT == 2 );&lt;br /&gt;
     SP_FIRST = 0                ,&lt;br /&gt;
     SP_SOME_PREF = SP_FIRST     ,&lt;br /&gt;
     SP_ANOTHA                   ,&lt;br /&gt;
 &lt;br /&gt;
     SP_COUNT&lt;br /&gt;
 } STRING_PREF_INDEX;&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! boost&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! boost release and debug build for linux&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
    # download latest boost, eg: boost_1_59_0 &lt;br /&gt;
    m@wallee:~/development$ 7z x boost_1_59_0.7z&lt;br /&gt;
    rm boost &amp;amp;&amp;amp; ln -s boost_1_59 boost&lt;br /&gt;
    cd boost&lt;br /&gt;
    build_boost_release_and_debug.sh&lt;br /&gt;
    # IMPORTANT: then patch .bashrc as instructed&lt;br /&gt;
    #     cmake-###/clean.sh and cmake-###/build.sh are customized to match&lt;br /&gt;
    #     (and older eclipse and server/nix/bootstrap.sh) &lt;br /&gt;
To upgrade a CMake project:&lt;br /&gt;
    cd cmake-###/&lt;br /&gt;
    ./clean.sh&lt;br /&gt;
    ./build.sh&lt;br /&gt;
To upgrade an older autotools project:&lt;br /&gt;
    cd nix&lt;br /&gt;
    make distclean  # removes nasty .deps folders that link to old boost if you let them&lt;br /&gt;
    make clean      # removes .o files etc&lt;br /&gt;
    cd ../build-Release &amp;amp;&amp;amp; make distclean &amp;amp;&amp;amp; make clean&lt;br /&gt;
    cd ../build-Debug &amp;amp;&amp;amp; make distclean &amp;amp;&amp;amp; make clean&lt;br /&gt;
    cd ..&lt;br /&gt;
    ./bootstrap force release&lt;br /&gt;
    ./bootstrap force debug&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! boost release and debug build for Windows&lt;br /&gt;
|-&lt;br /&gt;
| Open a VS2015 x64 Native Tools Command Prompt.  &lt;br /&gt;
EITHER: for new installs, you have to run bootstrap.bat first, it will build b2; &lt;br /&gt;
OR: for reruns, remove boost dirs: [bin.v2, stage].&lt;br /&gt;
Then build 64-bit:&lt;br /&gt;
 cd &amp;quot;....\boost_1_59_0&amp;quot;&lt;br /&gt;
 b2 toolset=msvc variant=release,debug link=static address-model=64&lt;br /&gt;
 rem trying to avoid excessive options, assuming I don&#039;t need these: threading=multi&lt;br /&gt;
 (old stuff)&lt;br /&gt;
       --toolset=msvc-14.0 address-model=64 --build-type=complete --stagedir=windows_lib\x64 stage&lt;br /&gt;
       Now open VS2013 x86 Native Tools Command Prompt and build 32-bit:&lt;br /&gt;
       cd &amp;quot;C:\Michael&#039;s Data\development\sixth_column\boost_1_55_0&amp;quot;&lt;br /&gt;
       bjam --toolset=msvc-12.0 address-model=32 --build-type=complete --stagedir=windows_lib\x86 stage&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! boost regex (very similar to c++11, with LESS BUGS and MORE POWER)&lt;br /&gt;
|-&lt;br /&gt;
| boost regex does everything you could need, take your time to get it right&lt;br /&gt;
* regex_search will work hard to find substrings, while regex_match requires your regex to match entire input&lt;br /&gt;
* smatch is a great way to get back a bunch of iterators to the results&lt;br /&gt;
example:&lt;br /&gt;
    virtual bool url_upgrade_any_old_semver(string&amp;amp; url)&lt;br /&gt;
    {&lt;br /&gt;
      // Perform a regex to update the embedded version if needed.&lt;br /&gt;
      // We have to see if (1) we have a semver and (2) it is not the current semver.&lt;br /&gt;
      // Only then do we take action.&lt;br /&gt;
      boost::regex regex(&amp;quot;/([v0-9.]+?)/(.*)&amp;quot;);&lt;br /&gt;
      boost::smatch sm_res;&lt;br /&gt;
      if (boost::regex_match(url,sm_res,regex,boost::match_default))&lt;br /&gt;
      {&lt;br /&gt;
        string incoming_semver(sm_res[1].first,sm_res[1].second);&lt;br /&gt;
        if (incoming_semver != semanticVersion())&lt;br /&gt;
        {&lt;br /&gt;
          url = string(&amp;quot;/&amp;quot;)+semanticVersion()+&amp;quot;/&amp;quot;+string(sm_res[2].first,sm_res[2].second);&lt;br /&gt;
          return true;&lt;br /&gt;
        }      &lt;br /&gt;
      }&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
results:&lt;br /&gt;
      original string:    string(sm_res[0].first,sm_res[0].second);&lt;br /&gt;
      first group:        string(sm_res[1].first,sm_res[1].second);&lt;br /&gt;
      second group:       string(sm_res[2].first,sm_res[2].second);&lt;br /&gt;
      etc.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C++ libraries&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! String escape formatting across different languages and systems&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* c++ to JSON: always use nlohmann::json j.dump() to encode, to ensure strings are properly escaped&lt;br /&gt;
* JSON to c++: always use nlohmann::json j.parse() &amp;quot;&lt;br /&gt;
* c++ to Javascript: use raw_to_Javascript() to properly escape&lt;br /&gt;
* c++ to sqlite: use SqliteLocalModel::safestr(), which uses double_doublequotes(str)&lt;br /&gt;
|}&lt;br /&gt;
[[Postgres]]&lt;br /&gt;
&lt;br /&gt;
[[Simple-Web-Server]]&lt;br /&gt;
&lt;br /&gt;
[[Robot Operating System]]&lt;br /&gt;
&lt;br /&gt;
[[C++ https libraries]]&lt;br /&gt;
&lt;br /&gt;
[[Configure Qt development on Windows + Mac + linux]]&lt;br /&gt;
&lt;br /&gt;
[[Build the TagLib library with Visual Studio 2013]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C/C++ building/linking&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gcc makefile pain&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* I went through a LOT of pain to determine that gcc requires libraries to be listed AFTER the source and output parameters&lt;br /&gt;
* set LD_LIBRARY_PATH to point to your libs if they are not in system location&lt;br /&gt;
* Make sure Makefile uses TABS NOT SPACES.  it&#039;s a FACT OF LIFE.  hate it if you want.  plenty more things to hate about linux/C as well.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! gcc install multiple versions in ubuntu (4 and 5 in wily, eg)&lt;br /&gt;
|-&lt;br /&gt;
| My code will not compile with gcc 5, the version provided with Ubuntu wily.&lt;br /&gt;
It gives warnings like this:&lt;br /&gt;
 /home/m/development/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:547:34: warning: ‘template&amp;lt;class&amp;gt; class std::auto_ptr’ is deprecated [-Wdeprecated-declarations]&lt;br /&gt;
and outright errors like this:&lt;br /&gt;
 depbase=`echo AtServer.o | sed &#039;s|[^/]*$|.deps/&amp;amp;|;s|\.o$||&#039;`;\&lt;br /&gt;
 g++ -DPACKAGE_NAME=\&amp;quot;at_server\&amp;quot; -DPACKAGE_TARNAME=\&amp;quot;at_server\&amp;quot; -DPACKAGE_VERSION=\&amp;quot;1.0\&amp;quot; -DPACKAGE_STRING=\&amp;quot;at_server\ 1.0\&amp;quot; -DPACKAGE_BUGREPORT=\&amp;quot;m@abettersoftware.com\&amp;quot; -DPACKAGE_URL=\&amp;quot;\&amp;quot; -DPACKAGE=\&amp;quot;at_server\&amp;quot; -DVERSION=\&amp;quot;1.0\&amp;quot; -I. -I../../src  -I/home/m/development/Reusable/c++ -I/home/m/development/Reusable/c++/sqlite -std=c++11 -I/home/m/development/boost_1_59_0  -ggdb3 -O0 -std=c++11 -MT AtServer.o -MD -MP -MF $depbase.Tpo -c -o AtServer.o ../../src/AtServer.cpp &amp;amp;&amp;amp;\&lt;br /&gt;
 mv -f $depbase.Tpo $depbase.Po&lt;br /&gt;
 In file included from /usr/include/c++/5/bits/stl_algo.h:60:0,&lt;br /&gt;
                 from /usr/include/c++/5/algorithm:62,&lt;br /&gt;
                 from /usr/include/c++/5/ext/slist:47,&lt;br /&gt;
                 from /home/m/development/boost_1_59_0/boost/algorithm/string/std/slist_traits.hpp:16,&lt;br /&gt;
                 from /home/m/development/boost_1_59_0/boost/algorithm/string/std_containers_traits.hpp:23,&lt;br /&gt;
                 from /home/m/development/boost_1_59_0/boost/algorithm/string.hpp:18,&lt;br /&gt;
                 from /home/m/development/Reusable/c++/utilities.hpp:4,&lt;br /&gt;
                 from ../../src/MemoryModel.hpp:11,&lt;br /&gt;
                 from ../../src/SqliteLocalModel.hpp:13,&lt;br /&gt;
                 from ../../src/AtServer.cpp:70:&lt;br /&gt;
 /usr/include/c++/5/bits/algorithmfwd.h:573:13: error: initializer provided for function&lt;br /&gt;
     noexcept(__and_&amp;lt;is_nothrow_move_constructible&amp;lt;_Tp&amp;gt;,&lt;br /&gt;
             ^&lt;br /&gt;
 /usr/include/c++/5/bits/algorithmfwd.h:582:13: error: initializer provided for function&lt;br /&gt;
     noexcept(noexcept(swap(*__a, *__b)))&lt;br /&gt;
&lt;br /&gt;
You can set up the update-alternatives tool to switch out the symlinks:&lt;br /&gt;
 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9&lt;br /&gt;
 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 20 --slave /usr/bin/g++ g++ /usr/bin/g++-5&lt;br /&gt;
BUT that seems BAD to me to switch out the compiler used by the SYSTEM.  Instead, we should specify the compiler required by the PROJECT.  This is supposed to do it, but it still uses /usr/include/c++/5, which seems wrong, and gives me errors:&lt;br /&gt;
 CC=gcc-4.9&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[git]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Debugging&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Chrome capture large JSON variable&lt;br /&gt;
|- &lt;br /&gt;
| This is just pointlessly bizarre:&lt;br /&gt;
* hit a breakpoint in the chrome debugger&lt;br /&gt;
* right-click a variable and say &amp;quot;copy to global variable&amp;quot; (console will show name, typically &amp;quot;temp1&amp;quot;)&lt;br /&gt;
* push the variable to the clipboard by typing this in the console:&lt;br /&gt;
 copy(temp1)&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Visual Studio Code capture large string variable&lt;br /&gt;
|- &lt;br /&gt;
| While debugging, you can use the Debug Console to print memory, including the content of strings that are clipped by default in the variables and watch windows.&lt;br /&gt;
 View &amp;gt; Open View &amp;gt; Debug Console&lt;br /&gt;
From there, send gdb a command to print memory – 300 characters of a string in this example:&lt;br /&gt;
 -exec x/300sb Query.c_str()&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Qt Creator conditional breakpoint&lt;br /&gt;
|-&lt;br /&gt;
| To break on line number with string condition:&lt;br /&gt;
* Set the breakpoint on the line as usual: F9 or click in left border&lt;br /&gt;
* In the breakpoints list, rclick Edit&lt;br /&gt;
* Add a condition; to break on a string value, THIS WORKS:&lt;br /&gt;
       &lt;br /&gt;
          ((int)strcmp(strSymbol.c_str(), &amp;quot;GMO&amp;quot;)) == 0&lt;br /&gt;
      &lt;br /&gt;
* BUT THERE IS A PRICE TO PAY.  qt/gcc won&#039;t continue properly, unless you sset ANOTHER common breakpoint, hit it, and resume from that.  It appears gcc continues (we hit the breakpoint after all), but qt does no logging or debugging, bah&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Qt Creator and linux debug libraries&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* I was able to build lws in debug, install in /usr/local, then I could step right into its code&lt;br /&gt;
 m@case:~/development/causam/git/np/nop-bigress-client-c$ ./build_lws_debug&lt;br /&gt;
  Install the project...&lt;br /&gt;
  -- Install configuration: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
  -- Installing: /usr/local/lib/pkgconfig/libwebsockets.pc&lt;br /&gt;
  -- Installing: /usr/local/lib/libwebsockets.a&lt;br /&gt;
  -- Up-to-date: /usr/local/include/libwebsockets.h&lt;br /&gt;
  (etc)&lt;br /&gt;
* Signals: At some point I needed to force gdb to pass SIGINT, SIGPIPE... signals to the app instead of gdb, after ssl kept causing Qt to pop a message and break in the debugger.  To do so:&lt;br /&gt;
        Qt Creator-&amp;gt;Options-&amp;gt;Debugger-&amp;gt;&lt;br /&gt;
            [ ] Show a message box when receiving a signal&lt;br /&gt;
            Debugger Helper Customization: handle SIGPIPE pass nostop noprint&lt;br /&gt;
* You should be able to install debug builds of libraries into /usr/local (as mentioned above).  Older notes if you can&#039;t get that going:  To debug into an included library that is not installed system-wide:&lt;br /&gt;
 use Tools-&amp;gt;Options-&amp;gt;General-&amp;gt;Source Paths Map&lt;br /&gt;
  source: /home/m/development/causam/git/nop-bigress-client-c/cmake-debug&lt;br /&gt;
    that&#039;s the COMPLETE PATH TO DEBUG EXE&lt;br /&gt;
  target: /home/m/development/causam/git/libwebsockets-master/lib&lt;br /&gt;
    at first i thought this would work: /usr/local/lib&lt;br /&gt;
    but i did a static build so i needed teh actual exe!  COOL&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! QT Creator valgrind EASY&lt;br /&gt;
|- &lt;br /&gt;
| Valgrind is easy to use.  Just find debugger pane top-left dropdown, switch mode from Debugger to Memcheck, and restart debugger.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c/c++ gdb debugging&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
 (gdb) help break&lt;br /&gt;
 Set breakpoint at specified line or function.&lt;br /&gt;
 Argument may be line number, function name, or &amp;quot;*&amp;quot; and an address.&lt;br /&gt;
 If line number is specified, break at start of code for that line.&lt;br /&gt;
 If function is specified, break at start of code for that function.&lt;br /&gt;
 If an address is specified, break at that exact address.&lt;br /&gt;
 With no arg, uses current execution address of selected stack frame.&lt;br /&gt;
 This is useful for breaking on return to a stack frame.&lt;br /&gt;
 &lt;br /&gt;
 Multiple breakpoints at one place are permitted, and useful if conditional.    &lt;br /&gt;
 &lt;br /&gt;
 Do &amp;quot;help breakpoints&amp;quot; for info on other commands dealing with breakpoints.&lt;br /&gt;
|- 		&lt;br /&gt;
| ddd gives you a front end.  I need to use it more, compare to other options&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Library handling in linux&lt;br /&gt;
|-&lt;br /&gt;
| gcc library basics (good to know for autotools and CMake too)&lt;br /&gt;
* The gcc -l command line option specifies a specific library NAME.  It will add the rest to give you (eg) lib[NAME].a&lt;br /&gt;
* Specify the library search path with the -L option.  Things that you as a user install seem to default to /usr/local/lib&lt;br /&gt;
* This will link myprogram with the static library libfoo.a in the folder /home/me/foo/lib.&lt;br /&gt;
        gcc -o myprogram -lfoo -L/home/me/foo/lib myprogram.c&lt;br /&gt;
Tools to check library dependencies:&lt;br /&gt;
* ldd [executable]&lt;br /&gt;
* objdump -p /path/to/program | grep NEEDED&lt;br /&gt;
* objdump -x [object.so]&lt;br /&gt;
* readelf -d [exe]&lt;br /&gt;
* sudo pldd &amp;lt;PID&amp;gt;&lt;br /&gt;
* sudo pmap &amp;lt;PID&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Cross Compiling]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! C - Create a portable command line C project in Visual Studio &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
    Visual Studio: File -&amp;gt; New -&amp;gt; project&lt;br /&gt;
    Visual C++ -&amp;gt; Win32 -&amp;gt; Win32 Console Application&lt;br /&gt;
    name: oms_with_emap&lt;br /&gt;
    next -&amp;gt; click OFF precompiled header checkbox (even tho it didn&#039;t seem to respect it)&lt;br /&gt;
    you&#039;ll get a _tmain(..., TCHAR*...)&lt;br /&gt;
    change it to main(..., char*...)&lt;br /&gt;
    change the project to explicitly say &amp;quot;Not using precompiled header&amp;quot;&lt;br /&gt;
    remove the f&#039;in stdafx.h&lt;br /&gt;
    recompile!  should be clean&lt;br /&gt;
    vs will recognize C files and compile accordingly&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Javascript]]&lt;br /&gt;
|}&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Node.js]]&lt;br /&gt;
|}&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[React]]&lt;br /&gt;
|}&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Vite]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[JSON]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[HTML]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[CSS]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! SQL&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! Count records within a range&lt;br /&gt;
|-&lt;br /&gt;
| This groups records into ranges, sorts by them, and gives a count, sweet:&lt;br /&gt;
    select count(*), id/1000000 as groupid from AccountHistory group by groupid;&lt;br /&gt;
|}&lt;br /&gt;
[[postgres]] - [[sqlite]] - [[mysql]] - [[SQL Server]] - [[Robo 3T]] - [[DBeaver]] - [[pgadmin4]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Meteor]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Android]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Arduino]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Raspberry Pi]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[iOS]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[.NET Core]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Java]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Kotlin]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Maven]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Scala]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Python]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Go]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! PHP&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! php debugging&lt;br /&gt;
|-&lt;br /&gt;
| Tail these:&lt;br /&gt;
 tail -f /var/log/apache2/sitelogs/thedigitalage.org/ssl_error_log&lt;br /&gt;
 tail -f /var/log/ampache-tda/ampache.(today).log&lt;br /&gt;
|-&lt;br /&gt;
| This leads to too much noise, not needed...&lt;br /&gt;
 emacs /etc/php/apache2-php5.3/php.ini&lt;br /&gt;
   display_errors = On&lt;br /&gt;
 /etc/init.d/apache restart&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Bash basics]] but please prefer node or python :-)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===========================================================================================================================================================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! misc&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! SVN repo move across servers&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
* use a tool like VisualSVN to stop SVN server&lt;br /&gt;
* copy the repo&#039;s entire svn server directory, eg: c:\svn\Software&lt;br /&gt;
* copy it into the new server under a unique name, eg: c:\svn\NewSoftware&lt;br /&gt;
* use a tool like VisualSVN to restart SVN server&lt;br /&gt;
You should now have the new code, accessible as usual from svn.&lt;br /&gt;
NOTE from Tom: If you move code around, make sure you tag it, then copy the tag, to preserve history (as opposed to directly moving the folder).  Weird but true.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! SQL Server 2008+ proper upsert using MERGE&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
        -- We need an &amp;quot;upsert&amp;quot;: if record exists, update it, otherwise insert.&lt;br /&gt;
        -- There are several options to do that.&lt;br /&gt;
        -- Trying to do it correctly means...&lt;br /&gt;
        --		1) use a lock or transaction to make the upsert atomic&lt;br /&gt;
        --		2) use the best-available operation to maximize performance&lt;br /&gt;
        -- SQL Server 2008 has MERGE which may be slightly more efficient than &lt;br /&gt;
        -- separate check &amp;amp;&amp;amp; (insert||update) steps.  And we can do it with&lt;br /&gt;
        -- a single lock instead of a full transaction (which may be better?).&lt;br /&gt;
        -- It&#039;s messy to code up though since three blocks of fields must be specified.  &lt;br /&gt;
        -- Cest la vie.&lt;br /&gt;
        MERGE [dbo].[FACT_DCSR_RemPeriodMonthlyReport] WITH (HOLDLOCK) AS rpmr&lt;br /&gt;
        USING (SELECT @ID AS ID) AS new_foo&lt;br /&gt;
              ON rpmr.ID = new_foo.ID&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                @last_months_year as DCSRYear,&lt;br /&gt;
                @last_month as DCSRMonth,&lt;br /&gt;
                @last_month_name as MonthName,&lt;br /&gt;
                Device_Type_ID,&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
        WHEN MATCHED THEN&lt;br /&gt;
            UPDATE&lt;br /&gt;
                    SET f.UpdateSpid = @@SPID, &lt;br /&gt;
                    UpdateTime = SYSDATETIME() &lt;br /&gt;
        WHEN NOT MATCHED THEN&lt;br /&gt;
            INSERT&lt;br /&gt;
              (&lt;br /&gt;
                    ID, &lt;br /&gt;
                    InsertSpid, &lt;br /&gt;
                    InsertTime&lt;br /&gt;
              )&lt;br /&gt;
            VALUES&lt;br /&gt;
              (&lt;br /&gt;
                    new_foo.ID, &lt;br /&gt;
                    @@SPID, &lt;br /&gt;
                    SYSDATETIME()&lt;br /&gt;
              );&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Web Services]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! [[Firefox Addon development]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ Create a portable autotools C++ project in linux&lt;br /&gt;
|-&lt;br /&gt;
| (OLD, USE CMAKE NOW)&lt;br /&gt;
&lt;br /&gt;
For anything serious, it&#039;s best to clone an existing project&#039;s skeleton.&lt;br /&gt;
* main.cpp&lt;br /&gt;
* MVC code&lt;br /&gt;
* nix/copy_from folder&lt;br /&gt;
* make sure .bashrc is configured for boost&lt;br /&gt;
* nix$  bootstrap_autotools_project.sh force release debug&lt;br /&gt;
* set up eclipse according to screenshots in [[Eclipse]]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
! c++ Create a portable C++ project in Visual Studio &lt;br /&gt;
|-&lt;br /&gt;
| (OLD, USE CMAKE NOW)&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have existing code, it&#039;s probably best to create a project_name.cpp file with your main() function.&lt;br /&gt;
 int main( int argc, char * argv[] )&lt;br /&gt;
 { &lt;br /&gt;
     return 0;&lt;br /&gt;
 }&lt;br /&gt;
Then in Visual Studio...&lt;br /&gt;
 File-&amp;gt;New-&amp;gt;Project from existing code&lt;br /&gt;
 C++&lt;br /&gt;
 (then use mostly defaults on this page, once you provide file location and project name)&lt;br /&gt;
 Project file location:  &amp;lt;base&amp;gt;\project_name&lt;br /&gt;
 Project name: project_name&lt;br /&gt;
 [x] Add files from these folders&lt;br /&gt;
    Add subs  &lt;br /&gt;
    [x]        &amp;lt;base&amp;gt;\project_name&lt;br /&gt;
 NEXT&lt;br /&gt;
 Use Visual Studio&lt;br /&gt;
   Console application project&lt;br /&gt;
   No ATL, MFC, CLR&lt;br /&gt;
 NEXT&lt;br /&gt;
 NEXT&lt;br /&gt;
 FINISH&lt;br /&gt;
Then add Reusable and boost include and lib paths:&lt;br /&gt;
Example if you built boost according to notes below:&lt;br /&gt;
 Project-&amp;gt;Properties-&amp;gt;All Configurations-&amp;gt;Configuration Properties-&amp;gt;VC++ Directories-&amp;gt;Include Directories-&amp;gt;&lt;br /&gt;
    $(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\..\Reusable\c++&lt;br /&gt;
 INCLUDE: C:\Software Development\boost_1_53_0&lt;br /&gt;
 LIB: C:\Software Development\boost_1_53_0\stage\lib&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Freman&amp;diff=7905</id>
		<title>Freman</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Freman&amp;diff=7905"/>
		<updated>2025-12-30T19:54:35Z</updated>

		<summary type="html">&lt;p&gt;M: /* Keyboard */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freman is a 2024 Mac Mini in the server rack.&lt;br /&gt;
&lt;br /&gt;
There are a few ways to access and do dev on it:&lt;br /&gt;
* Directly via KVM+Sony input switch; pro: this is the native acceleration and feel; con: well, it&#039;s a Mac&lt;br /&gt;
* Headless via VNC, specifically using [[Remmina]] on [[cast]; pro: just switch to workspace 6; con: slower&lt;br /&gt;
* Code on cast, push code and build and etc. via terminal; pro: awesome comfort; con: WIP&lt;br /&gt;
&lt;br /&gt;
I bought it in 2025/10 but Apple idiots say this 2024 is their &amp;quot;current release&amp;quot; (for over a year now), and even sales doesn&#039;t know when next Mini will drop.  I hate Apple.&lt;br /&gt;
&lt;br /&gt;
== Development configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Install software ===&lt;br /&gt;
* Install Xcode from the Apple Store&lt;br /&gt;
* Install [developer.apple.com/sf-symbols/|SF Symbols]&lt;br /&gt;
* Install [https://brew.sh/ homebrew] AFTER Xcode (it will then include Xcode stuff)&lt;br /&gt;
* Install ne&lt;br /&gt;
 brew install ne&lt;br /&gt;
 ne .zshrc # and set EDITOR=ne, so meta&lt;br /&gt;
* Install wget, git, meld&lt;br /&gt;
 brew install wget git meld&lt;br /&gt;
* Install nvm, npm, node&lt;br /&gt;
NOTE: again, must be done AFTER you install Xcode, but also after you create .zshrc.  Do NOT use homebrew, nvm github page says it is not supported.  Go to the github repo and run the script line from there in a terminal.&lt;br /&gt;
 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash&lt;br /&gt;
 # close and reopen terminal&lt;br /&gt;
 nvm install --lts&lt;br /&gt;
* (not sure i want this yet, it is Intel-based and requires this &amp;quot;Rosetta&amp;quot; bridge bullshit...) Pay $3 and install IconKit, saves hours of work to build stupid icon packs&lt;br /&gt;
* (not really using this yet...) Install TextMate: [https://macromates.com|download], open archive, drag app to Utilities, run, pin to dock (, add to path?)&lt;br /&gt;
&lt;br /&gt;
=== Dev env ===&lt;br /&gt;
* Set up repos&lt;br /&gt;
 cd&lt;br /&gt;
 mkdir development&lt;br /&gt;
 cd development&lt;br /&gt;
 git clone morosoph:development/scripts.git&lt;br /&gt;
 cd scripts/node/mah-haus&lt;br /&gt;
 npm install -g&lt;br /&gt;
 npm install -g @moodboom/git-semver&lt;br /&gt;
 cd ~/development&lt;br /&gt;
 mkdir -p thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 cd thedigitalage/AbetterTrader&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/server.git&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/scripts.git&lt;br /&gt;
 cd scripts/node/atci&lt;br /&gt;
 npm install -g&lt;br /&gt;
 cd ~/development/thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader.git&lt;br /&gt;
&lt;br /&gt;
* Open in Xcode: ~/development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader&lt;br /&gt;
&lt;br /&gt;
== Configure macOS ==&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
* Finder&lt;br /&gt;
 rclick in whitespace &amp;gt; Show View Options &amp;gt;&lt;br /&gt;
 [x] Always open in list view, sorted by name, hit Use as Defaults&lt;br /&gt;
&lt;br /&gt;
=== Mouse ===&lt;br /&gt;
==== Scrolling speed ====&lt;br /&gt;
Scrolling is super slow over Remmina, I found a fix [https://github.com/TigerVNC/tigervnc/issues/1741#issuecomment-2628649266 here].&lt;br /&gt;
&lt;br /&gt;
The app is called &amp;quot;mos&amp;quot;:&lt;br /&gt;
 brew install mos &lt;br /&gt;
 xattr -d com.apple.quarantine /Applications/Mos.app&lt;br /&gt;
 open /Applications/Mos.app&lt;br /&gt;
&lt;br /&gt;
BUT you have to run it every time you log in.  AND it forces natural scrolling.  I need a better fix.  FREMAN IS ICE COLD SLOW.&lt;br /&gt;
&lt;br /&gt;
==== Disable horrific natural scrolling ====&lt;br /&gt;
Apple BORG now forces natural scrolling with no UI toggle.  Hack it off with this:&lt;br /&gt;
 defaults write -g com.apple.swipescrolldirection -bool NO&lt;br /&gt;
 # log out/in&lt;br /&gt;
&lt;br /&gt;
=== Keyboard ===&lt;br /&gt;
* Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements] key mapping tool, oh yeah&lt;br /&gt;
* Run the install link in the Installation instructions at [https://github.com/rux616/karabiner-windows-mode this windows-mode repo] to get all the editor keys we NEED&lt;br /&gt;
** Older: Click predefined rules by community, search for &#039;&#039;&#039;&#039;PC-Style Shortcuts&#039;&#039;&#039;&#039; pack, wowza&lt;br /&gt;
(ok that didn&#039;t handle Ctrl-Insert (copy))&lt;br /&gt;
* Go through all the macOS permissions loosening to allow it access - you will NOT REGRET IT&lt;br /&gt;
* I could NOT find Ctrl-Ins that worked, even tho karabiner-windows-mode has TWO (they say you can&#039;t enable more than one but i tried them each separately).&lt;br /&gt;
* So, edit the file at ~/.config/karabiner/karabiner.json (Windows-Shift-. to show hidden files)&lt;br /&gt;
* You can find the karabiner-windows-mode overrides by searching for&lt;br /&gt;
 &amp;quot;key_code&amp;quot;:&amp;quot;insert&amp;quot;,&lt;br /&gt;
* Strip the conditions from it, and it will start to work!&lt;br /&gt;
&lt;br /&gt;
== Initial configuration ==&lt;br /&gt;
&lt;br /&gt;
* Plug it in&lt;br /&gt;
* WAIT&lt;br /&gt;
* Use connectors to get a mouse and kb connected to its USB-C ports; some mice/kb don&#039;t work but the Logitech/i-rocks ones do; WAIT for it to recognize them&lt;br /&gt;
* Upgrade to Tahoe&lt;br /&gt;
* Set the hostname via Apple &amp;gt; System Settings &amp;gt; Sharing (two places)&lt;br /&gt;
* Get MAC address from Apple &amp;gt; System Settings &amp;gt; Networking and update dnsmasq to give out a static IP; renew lease on mac&lt;br /&gt;
* Set display resolution to 4k (3840x2160): System Settings &amp;gt; Displays&lt;br /&gt;
&lt;br /&gt;
* Allow SSH: Apple &amp;gt; System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; check Remote Login&lt;br /&gt;
* [[Linux_barebones_quickstart#Copy_ssh_keys|Copy ssh keys]]&lt;br /&gt;
* Connect via ssh with kitty to teach Mac zfs terminal:&lt;br /&gt;
 m@cas[] kitty +kitten ssh freman&lt;br /&gt;
* Update /etc/ssh/sshd_config to disallow passwords, and restart sshd:&lt;br /&gt;
 sudo launchctl stop com.openssh.sshd&lt;br /&gt;
 sudo launchctl start com.openssh.sshd&lt;br /&gt;
* set aliases and a banner in ~/.zshrc&lt;br /&gt;
&lt;br /&gt;
* Allow VNC: System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; click Remote Management (i) &amp;gt; VNC users may control ON&lt;br /&gt;
* Turn off Lock Screen: Apple &amp;gt; System Settings &amp;gt; Privacy&amp;amp;Sec &amp;gt; Lock Screen &amp;gt; Turn display off NEVER, Require after off NEVER&lt;br /&gt;
* Ensure you can start a VNC session from cast using [[Remmina]]; note the full-screen toggle is RIGHT-CONTROL-F&lt;br /&gt;
** TODO mouse scrolls in very tiny increments; I can&#039;t seem to find any solutions yet; may need to try a different VNC client&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Freman&amp;diff=7904</id>
		<title>Freman</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Freman&amp;diff=7904"/>
		<updated>2025-12-30T18:41:24Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freman is a 2024 Mac Mini in the server rack.&lt;br /&gt;
&lt;br /&gt;
There are a few ways to access and do dev on it:&lt;br /&gt;
* Directly via KVM+Sony input switch; pro: this is the native acceleration and feel; con: well, it&#039;s a Mac&lt;br /&gt;
* Headless via VNC, specifically using [[Remmina]] on [[cast]; pro: just switch to workspace 6; con: slower&lt;br /&gt;
* Code on cast, push code and build and etc. via terminal; pro: awesome comfort; con: WIP&lt;br /&gt;
&lt;br /&gt;
I bought it in 2025/10 but Apple idiots say this 2024 is their &amp;quot;current release&amp;quot; (for over a year now), and even sales doesn&#039;t know when next Mini will drop.  I hate Apple.&lt;br /&gt;
&lt;br /&gt;
== Development configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Install software ===&lt;br /&gt;
* Install Xcode from the Apple Store&lt;br /&gt;
* Install [developer.apple.com/sf-symbols/|SF Symbols]&lt;br /&gt;
* Install [https://brew.sh/ homebrew] AFTER Xcode (it will then include Xcode stuff)&lt;br /&gt;
* Install ne&lt;br /&gt;
 brew install ne&lt;br /&gt;
 ne .zshrc # and set EDITOR=ne, so meta&lt;br /&gt;
* Install wget, git, meld&lt;br /&gt;
 brew install wget git meld&lt;br /&gt;
* Install nvm, npm, node&lt;br /&gt;
NOTE: again, must be done AFTER you install Xcode, but also after you create .zshrc.  Do NOT use homebrew, nvm github page says it is not supported.  Go to the github repo and run the script line from there in a terminal.&lt;br /&gt;
 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash&lt;br /&gt;
 # close and reopen terminal&lt;br /&gt;
 nvm install --lts&lt;br /&gt;
* (not sure i want this yet, it is Intel-based and requires this &amp;quot;Rosetta&amp;quot; bridge bullshit...) Pay $3 and install IconKit, saves hours of work to build stupid icon packs&lt;br /&gt;
* (not really using this yet...) Install TextMate: [https://macromates.com|download], open archive, drag app to Utilities, run, pin to dock (, add to path?)&lt;br /&gt;
&lt;br /&gt;
=== Dev env ===&lt;br /&gt;
* Set up repos&lt;br /&gt;
 cd&lt;br /&gt;
 mkdir development&lt;br /&gt;
 cd development&lt;br /&gt;
 git clone morosoph:development/scripts.git&lt;br /&gt;
 cd scripts/node/mah-haus&lt;br /&gt;
 npm install -g&lt;br /&gt;
 npm install -g @moodboom/git-semver&lt;br /&gt;
 cd ~/development&lt;br /&gt;
 mkdir -p thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 cd thedigitalage/AbetterTrader&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/server.git&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/scripts.git&lt;br /&gt;
 cd scripts/node/atci&lt;br /&gt;
 npm install -g&lt;br /&gt;
 cd ~/development/thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader.git&lt;br /&gt;
&lt;br /&gt;
* Open in Xcode: ~/development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader&lt;br /&gt;
&lt;br /&gt;
== Configure macOS ==&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
* Finder&lt;br /&gt;
 rclick in whitespace &amp;gt; Show View Options &amp;gt;&lt;br /&gt;
 [x] Always open in list view, sorted by name, hit Use as Defaults&lt;br /&gt;
&lt;br /&gt;
=== Mouse ===&lt;br /&gt;
==== Scrolling speed ====&lt;br /&gt;
Scrolling is super slow over Remmina, I found a fix [https://github.com/TigerVNC/tigervnc/issues/1741#issuecomment-2628649266 here].&lt;br /&gt;
&lt;br /&gt;
The app is called &amp;quot;mos&amp;quot;:&lt;br /&gt;
 brew install mos &lt;br /&gt;
 xattr -d com.apple.quarantine /Applications/Mos.app&lt;br /&gt;
 open /Applications/Mos.app&lt;br /&gt;
&lt;br /&gt;
BUT you have to run it every time you log in.  AND it forces natural scrolling.  I need a better fix.  FREMAN IS ICE COLD SLOW.&lt;br /&gt;
&lt;br /&gt;
==== Disable horrific natural scrolling ====&lt;br /&gt;
Apple BORG now forces natural scrolling with no UI toggle.  Hack it off with this:&lt;br /&gt;
 defaults write -g com.apple.swipescrolldirection -bool NO&lt;br /&gt;
 # log out/in&lt;br /&gt;
&lt;br /&gt;
=== Keyboard ===&lt;br /&gt;
* Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements] key mapping tool, oh yeah&lt;br /&gt;
* Click predefined rules by community, search for &#039;&#039;&#039;&#039;PC-Style Shortcuts&#039;&#039;&#039;&#039; pack, wowza&lt;br /&gt;
(ok that didn&#039;t handle Ctrl-Insert (copy) so I tried [https://github.com/rux616/karabiner-windows-mode this one] instead&lt;br /&gt;
* Go through all the macOS permissions loosening to allow it access - you will NOT REGRET IT&lt;br /&gt;
* I could NOT find Ctrl-Ins that worked, even tho karabiner-windows-mode has TWO (they say you can&#039;t enable more than one but i tried them each separately).&lt;br /&gt;
* So, edit the file at ~/.config/karabiner/karabiner.json (Windows-Shift-. to show hidden files)&lt;br /&gt;
* You can find the karabiner-windows-mode overrides by searching for&lt;br /&gt;
 &amp;quot;key_code&amp;quot;:&amp;quot;insert&amp;quot;,&lt;br /&gt;
* Strip the conditions from it, and it will start to work!&lt;br /&gt;
&lt;br /&gt;
== Initial configuration ==&lt;br /&gt;
&lt;br /&gt;
* Plug it in&lt;br /&gt;
* WAIT&lt;br /&gt;
* Use connectors to get a mouse and kb connected to its USB-C ports; some mice/kb don&#039;t work but the Logitech/i-rocks ones do; WAIT for it to recognize them&lt;br /&gt;
* Upgrade to Tahoe&lt;br /&gt;
* Set the hostname via Apple &amp;gt; System Settings &amp;gt; Sharing (two places)&lt;br /&gt;
* Get MAC address from Apple &amp;gt; System Settings &amp;gt; Networking and update dnsmasq to give out a static IP; renew lease on mac&lt;br /&gt;
* Set display resolution to 4k (3840x2160): System Settings &amp;gt; Displays&lt;br /&gt;
&lt;br /&gt;
* Allow SSH: Apple &amp;gt; System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; check Remote Login&lt;br /&gt;
* [[Linux_barebones_quickstart#Copy_ssh_keys|Copy ssh keys]]&lt;br /&gt;
* Connect via ssh with kitty to teach Mac zfs terminal:&lt;br /&gt;
 m@cas[] kitty +kitten ssh freman&lt;br /&gt;
* Update /etc/ssh/sshd_config to disallow passwords, and restart sshd:&lt;br /&gt;
 sudo launchctl stop com.openssh.sshd&lt;br /&gt;
 sudo launchctl start com.openssh.sshd&lt;br /&gt;
* set aliases and a banner in ~/.zshrc&lt;br /&gt;
&lt;br /&gt;
* Allow VNC: System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; click Remote Management (i) &amp;gt; VNC users may control ON&lt;br /&gt;
* Turn off Lock Screen: Apple &amp;gt; System Settings &amp;gt; Privacy&amp;amp;Sec &amp;gt; Lock Screen &amp;gt; Turn display off NEVER, Require after off NEVER&lt;br /&gt;
* Ensure you can start a VNC session from cast using [[Remmina]]; note the full-screen toggle is RIGHT-CONTROL-F&lt;br /&gt;
** TODO mouse scrolls in very tiny increments; I can&#039;t seem to find any solutions yet; may need to try a different VNC client&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Freman&amp;diff=7903</id>
		<title>Freman</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Freman&amp;diff=7903"/>
		<updated>2025-12-30T18:40:44Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Freman is a 2024 Mac Mini in the server rack.&lt;br /&gt;
&lt;br /&gt;
There are a few ways to access and do dev on it:&lt;br /&gt;
* Directly; pro: this is the native acceleration and feel; con: well, it&#039;s a Mac&lt;br /&gt;
* Headless via VNC, specifically using [[Remmina]] on [[cast]; pro: just switch to workspace 6; con: slower&lt;br /&gt;
* Code on cast, push code and build and etc. via terminal; pro: awesome comfort; con: WIP&lt;br /&gt;
&lt;br /&gt;
I bought it in 2025/10 but Apple idiots say this 2024 is their &amp;quot;current release&amp;quot; (for over a year now), and even sales doesn&#039;t know when next Mini will drop.  I hate Apple.&lt;br /&gt;
&lt;br /&gt;
== Development configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Install software ===&lt;br /&gt;
* Install Xcode from the Apple Store&lt;br /&gt;
* Install [developer.apple.com/sf-symbols/|SF Symbols]&lt;br /&gt;
* Install [https://brew.sh/ homebrew] AFTER Xcode (it will then include Xcode stuff)&lt;br /&gt;
* Install ne&lt;br /&gt;
 brew install ne&lt;br /&gt;
 ne .zshrc # and set EDITOR=ne, so meta&lt;br /&gt;
* Install wget, git, meld&lt;br /&gt;
 brew install wget git meld&lt;br /&gt;
* Install nvm, npm, node&lt;br /&gt;
NOTE: again, must be done AFTER you install Xcode, but also after you create .zshrc.  Do NOT use homebrew, nvm github page says it is not supported.  Go to the github repo and run the script line from there in a terminal.&lt;br /&gt;
 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash&lt;br /&gt;
 # close and reopen terminal&lt;br /&gt;
 nvm install --lts&lt;br /&gt;
* (not sure i want this yet, it is Intel-based and requires this &amp;quot;Rosetta&amp;quot; bridge bullshit...) Pay $3 and install IconKit, saves hours of work to build stupid icon packs&lt;br /&gt;
* (not really using this yet...) Install TextMate: [https://macromates.com|download], open archive, drag app to Utilities, run, pin to dock (, add to path?)&lt;br /&gt;
&lt;br /&gt;
=== Dev env ===&lt;br /&gt;
* Set up repos&lt;br /&gt;
 cd&lt;br /&gt;
 mkdir development&lt;br /&gt;
 cd development&lt;br /&gt;
 git clone morosoph:development/scripts.git&lt;br /&gt;
 cd scripts/node/mah-haus&lt;br /&gt;
 npm install -g&lt;br /&gt;
 npm install -g @moodboom/git-semver&lt;br /&gt;
 cd ~/development&lt;br /&gt;
 mkdir -p thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 cd thedigitalage/AbetterTrader&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/server.git&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/scripts.git&lt;br /&gt;
 cd scripts/node/atci&lt;br /&gt;
 npm install -g&lt;br /&gt;
 cd ~/development/thedigitalage/AbetterTrader/frontend/iOS&lt;br /&gt;
 git clone morosoph:development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader.git&lt;br /&gt;
&lt;br /&gt;
* Open in Xcode: ~/development/thedigitalage/AbetterTrader/frontend/iOS/AbetterTrader&lt;br /&gt;
&lt;br /&gt;
== Configure macOS ==&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
* Finder&lt;br /&gt;
 rclick in whitespace &amp;gt; Show View Options &amp;gt;&lt;br /&gt;
 [x] Always open in list view, sorted by name, hit Use as Defaults&lt;br /&gt;
&lt;br /&gt;
=== Mouse ===&lt;br /&gt;
==== Scrolling speed ====&lt;br /&gt;
Scrolling is super slow over Remmina, I found a fix [https://github.com/TigerVNC/tigervnc/issues/1741#issuecomment-2628649266 here].&lt;br /&gt;
&lt;br /&gt;
The app is called &amp;quot;mos&amp;quot;:&lt;br /&gt;
 brew install mos &lt;br /&gt;
 xattr -d com.apple.quarantine /Applications/Mos.app&lt;br /&gt;
 open /Applications/Mos.app&lt;br /&gt;
&lt;br /&gt;
BUT you have to run it every time you log in.  AND it forces natural scrolling.  I need a better fix.  FREMAN IS ICE COLD SLOW.&lt;br /&gt;
&lt;br /&gt;
==== Disable horrific natural scrolling ====&lt;br /&gt;
Apple BORG now forces natural scrolling with no UI toggle.  Hack it off with this:&lt;br /&gt;
 defaults write -g com.apple.swipescrolldirection -bool NO&lt;br /&gt;
 # log out/in&lt;br /&gt;
&lt;br /&gt;
=== Keyboard ===&lt;br /&gt;
* Install [https://karabiner-elements.pqrs.org/ Karabiner-Elements] key mapping tool, oh yeah&lt;br /&gt;
* Click predefined rules by community, search for &#039;&#039;&#039;&#039;PC-Style Shortcuts&#039;&#039;&#039;&#039; pack, wowza&lt;br /&gt;
(ok that didn&#039;t handle Ctrl-Insert (copy) so I tried [https://github.com/rux616/karabiner-windows-mode this one] instead&lt;br /&gt;
* Go through all the macOS permissions loosening to allow it access - you will NOT REGRET IT&lt;br /&gt;
* I could NOT find Ctrl-Ins that worked, even tho karabiner-windows-mode has TWO (they say you can&#039;t enable more than one but i tried them each separately).&lt;br /&gt;
* So, edit the file at ~/.config/karabiner/karabiner.json (Windows-Shift-. to show hidden files)&lt;br /&gt;
* You can find the karabiner-windows-mode overrides by searching for&lt;br /&gt;
 &amp;quot;key_code&amp;quot;:&amp;quot;insert&amp;quot;,&lt;br /&gt;
* Strip the conditions from it, and it will start to work!&lt;br /&gt;
&lt;br /&gt;
== Initial configuration ==&lt;br /&gt;
&lt;br /&gt;
* Plug it in&lt;br /&gt;
* WAIT&lt;br /&gt;
* Use connectors to get a mouse and kb connected to its USB-C ports; some mice/kb don&#039;t work but the Logitech/i-rocks ones do; WAIT for it to recognize them&lt;br /&gt;
* Upgrade to Tahoe&lt;br /&gt;
* Set the hostname via Apple &amp;gt; System Settings &amp;gt; Sharing (two places)&lt;br /&gt;
* Get MAC address from Apple &amp;gt; System Settings &amp;gt; Networking and update dnsmasq to give out a static IP; renew lease on mac&lt;br /&gt;
* Set display resolution to 4k (3840x2160): System Settings &amp;gt; Displays&lt;br /&gt;
&lt;br /&gt;
* Allow SSH: Apple &amp;gt; System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; check Remote Login&lt;br /&gt;
* [[Linux_barebones_quickstart#Copy_ssh_keys|Copy ssh keys]]&lt;br /&gt;
* Connect via ssh with kitty to teach Mac zfs terminal:&lt;br /&gt;
 m@cas[] kitty +kitten ssh freman&lt;br /&gt;
* Update /etc/ssh/sshd_config to disallow passwords, and restart sshd:&lt;br /&gt;
 sudo launchctl stop com.openssh.sshd&lt;br /&gt;
 sudo launchctl start com.openssh.sshd&lt;br /&gt;
* set aliases and a banner in ~/.zshrc&lt;br /&gt;
&lt;br /&gt;
* Allow VNC: System Settings &amp;gt; General &amp;gt; Sharing &amp;gt; click Remote Management (i) &amp;gt; VNC users may control ON&lt;br /&gt;
* Turn off Lock Screen: Apple &amp;gt; System Settings &amp;gt; Privacy&amp;amp;Sec &amp;gt; Lock Screen &amp;gt; Turn display off NEVER, Require after off NEVER&lt;br /&gt;
* Ensure you can start a VNC session from cast using [[Remmina]]; note the full-screen toggle is RIGHT-CONTROL-F&lt;br /&gt;
** TODO mouse scrolls in very tiny increments; I can&#039;t seem to find any solutions yet; may need to try a different VNC client&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Brave&amp;diff=7902</id>
		<title>Brave</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Brave&amp;diff=7902"/>
		<updated>2025-12-29T17:53:41Z</updated>

		<summary type="html">&lt;p&gt;M: /* Keys */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configure ==&lt;br /&gt;
&lt;br /&gt;
=== Keys ===&lt;br /&gt;
&lt;br /&gt;
* Alt-D: edit url&lt;br /&gt;
* Ctrl-D: add bookmark&lt;br /&gt;
* Ctrl-PgUp/Dn: Navigate tabs&lt;br /&gt;
* Ctrl-Shift-PgUp/Dn: Move tabs&lt;br /&gt;
* Ctrl-Shift-Del: Move tab to new window (*)&lt;br /&gt;
* Ctrl-Shift-Ins: Duplicate tab (*)&lt;br /&gt;
&lt;br /&gt;
(*) Not a default, but always set [brave://settings/system/shortcuts here] in all profiles.&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
Immediately change these Settings on any new profile:&lt;br /&gt;
* Get started &amp;gt; Profile name and icon &amp;gt; customize it!&lt;br /&gt;
* Get started &amp;gt; New Tab Page &amp;gt; shows &amp;gt; Homepage&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Show home button ON, set to bitpost.com&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Brave Rewards, Brave Wallet, Sidebar &amp;gt; OFF&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Show wide address bar, show full urls &amp;gt; ON&lt;br /&gt;
* Appearance &amp;gt; Sidebar &amp;gt; Show: never&lt;br /&gt;
* (NO) Appearance &amp;gt; Content &amp;gt; (very bottom) Cycle through the most recently used tabs with Ctrl-Tab&lt;br /&gt;
* Sync &amp;gt; I have a chain &amp;gt; paste, toggle Sync everything ON&lt;br /&gt;
&lt;br /&gt;
TODO: consider playing with vertical tabs!  It&#039;s a mindfuck tho...&lt;br /&gt;
&lt;br /&gt;
=== Profiles ===&lt;br /&gt;
Profiles in Brave are AWESOME:&lt;br /&gt;
* Brave seems to remember what desktop the windows were on!!!  FINALLY&lt;br /&gt;
* For each profile, you get a name and customizable icon in the top-right of the toolbar, SO NICE&lt;br /&gt;
* Bookmarks etc. are all profile-specific, as expected&lt;br /&gt;
* You can sync a profile across machines (see #Sync)&lt;br /&gt;
&lt;br /&gt;
==== Finding Profile folder ====&lt;br /&gt;
You can start brave with a specific profile, like this:&lt;br /&gt;
 brave-browser --profile-directory=&#039;Profile 4&#039;&amp;amp;&lt;br /&gt;
This is a bit dicey as the folder you must provide does not actually match the profile name!  I used this bit of ugliness to get a map of name to folder:&lt;br /&gt;
&lt;br /&gt;
  💉 m@cast  [~/.config/BraveSoftware/Brave-Browser] grep -Po &amp;quot;\&amp;quot;name\&amp;quot;:\&amp;quot;[^\&amp;quot;]*?\&amp;quot;,\&amp;quot;(pa|usi)&amp;quot; * -R&lt;br /&gt;
 Default/Preferences:&amp;quot;name&amp;quot;:&amp;quot;moodboom&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 4/Preferences:&amp;quot;name&amp;quot;:&amp;quot;es-1&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 5/Preferences:&amp;quot;name&amp;quot;:&amp;quot;mdmdev-1&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 6/Preferences:&amp;quot;name&amp;quot;:&amp;quot;Profile 2&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 7/Preferences:&amp;quot;name&amp;quot;:&amp;quot;ig-1&amp;quot;,&amp;quot;usi&lt;br /&gt;
&lt;br /&gt;
==== Assign VSCode Launch to (re)use a Brave profile ====&lt;br /&gt;
When vscode starts its Javascript debugger, it uses a custom &amp;quot;user-data-dir&amp;quot; within its own config folder.  This means you start with a clean profile upon first use.  However, (after MUCH trial-and-horror), you can specify that it uses a precise profile within this custom user-data-dir.&lt;br /&gt;
&lt;br /&gt;
If you use a launch.json stanza like this, vscode will always use that specific profile.  You can then start customizing the profile, and your changes will stick across debugging sessions.  Awesome!&lt;br /&gt;
  &amp;quot;configurations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;Launch Brave&amp;quot;,&lt;br /&gt;
      &amp;quot;runtimeExecutable&amp;quot;: &amp;quot;/usr/bin/brave-browser&amp;quot;,&lt;br /&gt;
      // NOTE: This directory will be within .code/Code/User; specifying it allows reuse of a specific Profile there, nice.&lt;br /&gt;
      &amp;quot;runtimeArgs&amp;quot;: [ &amp;quot;--profile-directory=\&amp;quot;Profile 4\&amp;quot;&amp;quot; ],&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;chrome&amp;quot;,&lt;br /&gt;
      &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 5000,&lt;br /&gt;
      &amp;quot;url&amp;quot;: &amp;quot;http://localhost:8008&amp;quot;,&lt;br /&gt;
      &amp;quot;webRoot&amp;quot;: &amp;quot;${workspaceFolder}/src&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
That should be all you need to get usage of a consistent profile across sessions.  But... say you want to sync it across development environments... why not!  Read on...&lt;br /&gt;
&lt;br /&gt;
===== More Details =====&lt;br /&gt;
Again, we dig to get a map of profile names to folders.  First, run the debugger, and look for the process and params:&lt;br /&gt;
 ps ax|grep -Po brave.*config/Code/User/workspaceStorage/.*?profile&lt;br /&gt;
From that, you can extract a user-data-dir:&lt;br /&gt;
 --user-data-dir=/home/m/development/config/common/home/m/.config/Code/User/workspaceStorage/436f0a4c50203656e625d634df9e0ca9/ms-vscode.js-debug/.profile&lt;br /&gt;
NOTE that it seems that each vscode project has its own workspaceStorage!  Which is pretty crazy.  That means every dev project can have its own set of profiles.&lt;br /&gt;
&lt;br /&gt;
From the user-data-dir folder, you can get a map of profile name to folder:&lt;br /&gt;
 cd #your-user-data-dir#&lt;br /&gt;
 grep -Po &amp;quot;\&amp;quot;name\&amp;quot;:\&amp;quot;[^\&amp;quot;]*?\&amp;quot;,\&amp;quot;(pa|usi)&amp;quot; * -R&lt;br /&gt;
    &amp;quot;Profile 4&amp;quot;/Preferences:&amp;quot;name&amp;quot;:&amp;quot;es-2&amp;quot;,&amp;quot;usi&lt;br /&gt;
&lt;br /&gt;
Now that you know what is where.... Just like with &amp;quot;normal&amp;quot; profiles, you can sync them across machines.&lt;br /&gt;
&lt;br /&gt;
=== Set up sync ===&lt;br /&gt;
Do this for each profile:&lt;br /&gt;
* Settings &amp;gt; Sync &amp;gt; Start a new Sync Chain &amp;gt; Computer &amp;gt; copy Sync Chain Code &amp;gt; save in private&lt;br /&gt;
* Make sure Sync everything is toggled ON&lt;br /&gt;
* You can now paste this chain into another computer to sync this profile there&lt;br /&gt;
&lt;br /&gt;
== Backup ==&lt;br /&gt;
Synced brave profiles are so valuable!  So much so that you might want to back up the data.&lt;br /&gt;
&lt;br /&gt;
This includes three major chunks of data, but you can only export two:&lt;br /&gt;
* Export passwords to a safe place, from here:&lt;br /&gt;
 Settings &amp;gt; Autofill and passwords &amp;gt; Password Manager &amp;gt; (left pane) Settings &amp;gt; Export passwords&lt;br /&gt;
* Export bookmarks from here:&lt;br /&gt;
 Main Menu (top-right hamburger) &amp;gt; Bookmarks &amp;gt; Bookmars Manager &amp;gt; More (top-right ...) &amp;gt; Export&lt;br /&gt;
* Autofill (Payment methods, Addresses)&lt;br /&gt;
 Settings &amp;gt; Autofill and passwords &amp;gt; Payment methods, Addresses (view-only, no export)&lt;br /&gt;
&lt;br /&gt;
== [https://brave.com/linux/ Install] ==&lt;br /&gt;
Copy and paste this all in one shot!&lt;br /&gt;
 sudo curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg&lt;br /&gt;
 echo &amp;quot;deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main&amp;quot;|sudo tee /etc/apt/sources.list.d/brave-browser-release.list&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install brave-browser&lt;br /&gt;
&lt;br /&gt;
One annoying thing... the apt file searches all architectures and you&#039;ll get i386 errors, until you add &amp;quot;arch=amd64&amp;quot; like this:&lt;br /&gt;
 sudo emacs /etc/apt/sources.list.d/brave-browser-release.list&lt;br /&gt;
 &lt;br /&gt;
 deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg arch=amd64] https://brave-browser-apt-release.s3.brave.com/ stable main&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Profiles ===&lt;br /&gt;
At one point, maybe after a crash, my profiles stopped fully loading.  Passwords and history were not getting loaded.  I updated my system and rebooted and after a day or two of suffering they just came back on a reboot.  GOOD LORD I need them!  So... back them up...&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Brave&amp;diff=7901</id>
		<title>Brave</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Brave&amp;diff=7901"/>
		<updated>2025-12-29T17:52:51Z</updated>

		<summary type="html">&lt;p&gt;M: /* Keys */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configure ==&lt;br /&gt;
&lt;br /&gt;
=== Keys ===&lt;br /&gt;
&lt;br /&gt;
* Alt-D: edit url&lt;br /&gt;
* Ctrl-PgUp/Dn: Navigate tabs&lt;br /&gt;
* Ctrl-Shift-PgUp/Dn: Move tabs&lt;br /&gt;
* Ctrl-Shift-Del: Move tab to new window (*)&lt;br /&gt;
* Ctrl-Shift-Ins: Duplicate tab (*)&lt;br /&gt;
&lt;br /&gt;
(*) Not a default, but always set [brave://settings/system/shortcuts here] in all profiles.&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
Immediately change these Settings on any new profile:&lt;br /&gt;
* Get started &amp;gt; Profile name and icon &amp;gt; customize it!&lt;br /&gt;
* Get started &amp;gt; New Tab Page &amp;gt; shows &amp;gt; Homepage&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Show home button ON, set to bitpost.com&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Brave Rewards, Brave Wallet, Sidebar &amp;gt; OFF&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Show wide address bar, show full urls &amp;gt; ON&lt;br /&gt;
* Appearance &amp;gt; Sidebar &amp;gt; Show: never&lt;br /&gt;
* (NO) Appearance &amp;gt; Content &amp;gt; (very bottom) Cycle through the most recently used tabs with Ctrl-Tab&lt;br /&gt;
* Sync &amp;gt; I have a chain &amp;gt; paste, toggle Sync everything ON&lt;br /&gt;
&lt;br /&gt;
TODO: consider playing with vertical tabs!  It&#039;s a mindfuck tho...&lt;br /&gt;
&lt;br /&gt;
=== Profiles ===&lt;br /&gt;
Profiles in Brave are AWESOME:&lt;br /&gt;
* Brave seems to remember what desktop the windows were on!!!  FINALLY&lt;br /&gt;
* For each profile, you get a name and customizable icon in the top-right of the toolbar, SO NICE&lt;br /&gt;
* Bookmarks etc. are all profile-specific, as expected&lt;br /&gt;
* You can sync a profile across machines (see #Sync)&lt;br /&gt;
&lt;br /&gt;
==== Finding Profile folder ====&lt;br /&gt;
You can start brave with a specific profile, like this:&lt;br /&gt;
 brave-browser --profile-directory=&#039;Profile 4&#039;&amp;amp;&lt;br /&gt;
This is a bit dicey as the folder you must provide does not actually match the profile name!  I used this bit of ugliness to get a map of name to folder:&lt;br /&gt;
&lt;br /&gt;
  💉 m@cast  [~/.config/BraveSoftware/Brave-Browser] grep -Po &amp;quot;\&amp;quot;name\&amp;quot;:\&amp;quot;[^\&amp;quot;]*?\&amp;quot;,\&amp;quot;(pa|usi)&amp;quot; * -R&lt;br /&gt;
 Default/Preferences:&amp;quot;name&amp;quot;:&amp;quot;moodboom&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 4/Preferences:&amp;quot;name&amp;quot;:&amp;quot;es-1&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 5/Preferences:&amp;quot;name&amp;quot;:&amp;quot;mdmdev-1&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 6/Preferences:&amp;quot;name&amp;quot;:&amp;quot;Profile 2&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 7/Preferences:&amp;quot;name&amp;quot;:&amp;quot;ig-1&amp;quot;,&amp;quot;usi&lt;br /&gt;
&lt;br /&gt;
==== Assign VSCode Launch to (re)use a Brave profile ====&lt;br /&gt;
When vscode starts its Javascript debugger, it uses a custom &amp;quot;user-data-dir&amp;quot; within its own config folder.  This means you start with a clean profile upon first use.  However, (after MUCH trial-and-horror), you can specify that it uses a precise profile within this custom user-data-dir.&lt;br /&gt;
&lt;br /&gt;
If you use a launch.json stanza like this, vscode will always use that specific profile.  You can then start customizing the profile, and your changes will stick across debugging sessions.  Awesome!&lt;br /&gt;
  &amp;quot;configurations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;Launch Brave&amp;quot;,&lt;br /&gt;
      &amp;quot;runtimeExecutable&amp;quot;: &amp;quot;/usr/bin/brave-browser&amp;quot;,&lt;br /&gt;
      // NOTE: This directory will be within .code/Code/User; specifying it allows reuse of a specific Profile there, nice.&lt;br /&gt;
      &amp;quot;runtimeArgs&amp;quot;: [ &amp;quot;--profile-directory=\&amp;quot;Profile 4\&amp;quot;&amp;quot; ],&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;chrome&amp;quot;,&lt;br /&gt;
      &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 5000,&lt;br /&gt;
      &amp;quot;url&amp;quot;: &amp;quot;http://localhost:8008&amp;quot;,&lt;br /&gt;
      &amp;quot;webRoot&amp;quot;: &amp;quot;${workspaceFolder}/src&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
That should be all you need to get usage of a consistent profile across sessions.  But... say you want to sync it across development environments... why not!  Read on...&lt;br /&gt;
&lt;br /&gt;
===== More Details =====&lt;br /&gt;
Again, we dig to get a map of profile names to folders.  First, run the debugger, and look for the process and params:&lt;br /&gt;
 ps ax|grep -Po brave.*config/Code/User/workspaceStorage/.*?profile&lt;br /&gt;
From that, you can extract a user-data-dir:&lt;br /&gt;
 --user-data-dir=/home/m/development/config/common/home/m/.config/Code/User/workspaceStorage/436f0a4c50203656e625d634df9e0ca9/ms-vscode.js-debug/.profile&lt;br /&gt;
NOTE that it seems that each vscode project has its own workspaceStorage!  Which is pretty crazy.  That means every dev project can have its own set of profiles.&lt;br /&gt;
&lt;br /&gt;
From the user-data-dir folder, you can get a map of profile name to folder:&lt;br /&gt;
 cd #your-user-data-dir#&lt;br /&gt;
 grep -Po &amp;quot;\&amp;quot;name\&amp;quot;:\&amp;quot;[^\&amp;quot;]*?\&amp;quot;,\&amp;quot;(pa|usi)&amp;quot; * -R&lt;br /&gt;
    &amp;quot;Profile 4&amp;quot;/Preferences:&amp;quot;name&amp;quot;:&amp;quot;es-2&amp;quot;,&amp;quot;usi&lt;br /&gt;
&lt;br /&gt;
Now that you know what is where.... Just like with &amp;quot;normal&amp;quot; profiles, you can sync them across machines.&lt;br /&gt;
&lt;br /&gt;
=== Set up sync ===&lt;br /&gt;
Do this for each profile:&lt;br /&gt;
* Settings &amp;gt; Sync &amp;gt; Start a new Sync Chain &amp;gt; Computer &amp;gt; copy Sync Chain Code &amp;gt; save in private&lt;br /&gt;
* Make sure Sync everything is toggled ON&lt;br /&gt;
* You can now paste this chain into another computer to sync this profile there&lt;br /&gt;
&lt;br /&gt;
== Backup ==&lt;br /&gt;
Synced brave profiles are so valuable!  So much so that you might want to back up the data.&lt;br /&gt;
&lt;br /&gt;
This includes three major chunks of data, but you can only export two:&lt;br /&gt;
* Export passwords to a safe place, from here:&lt;br /&gt;
 Settings &amp;gt; Autofill and passwords &amp;gt; Password Manager &amp;gt; (left pane) Settings &amp;gt; Export passwords&lt;br /&gt;
* Export bookmarks from here:&lt;br /&gt;
 Main Menu (top-right hamburger) &amp;gt; Bookmarks &amp;gt; Bookmars Manager &amp;gt; More (top-right ...) &amp;gt; Export&lt;br /&gt;
* Autofill (Payment methods, Addresses)&lt;br /&gt;
 Settings &amp;gt; Autofill and passwords &amp;gt; Payment methods, Addresses (view-only, no export)&lt;br /&gt;
&lt;br /&gt;
== [https://brave.com/linux/ Install] ==&lt;br /&gt;
Copy and paste this all in one shot!&lt;br /&gt;
 sudo curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg&lt;br /&gt;
 echo &amp;quot;deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main&amp;quot;|sudo tee /etc/apt/sources.list.d/brave-browser-release.list&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install brave-browser&lt;br /&gt;
&lt;br /&gt;
One annoying thing... the apt file searches all architectures and you&#039;ll get i386 errors, until you add &amp;quot;arch=amd64&amp;quot; like this:&lt;br /&gt;
 sudo emacs /etc/apt/sources.list.d/brave-browser-release.list&lt;br /&gt;
 &lt;br /&gt;
 deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg arch=amd64] https://brave-browser-apt-release.s3.brave.com/ stable main&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Profiles ===&lt;br /&gt;
At one point, maybe after a crash, my profiles stopped fully loading.  Passwords and history were not getting loaded.  I updated my system and rebooted and after a day or two of suffering they just came back on a reboot.  GOOD LORD I need them!  So... back them up...&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Brave&amp;diff=7900</id>
		<title>Brave</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Brave&amp;diff=7900"/>
		<updated>2025-12-29T17:51:48Z</updated>

		<summary type="html">&lt;p&gt;M: /* Configure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configure ==&lt;br /&gt;
&lt;br /&gt;
=== Keys ===&lt;br /&gt;
&lt;br /&gt;
* Alt-D: edit url&lt;br /&gt;
* Ctrl-Shift-Del: Move tab to new window (*)&lt;br /&gt;
* Ctrl-Shift-Ins: Duplicate tab (*)&lt;br /&gt;
&lt;br /&gt;
\* Not a default, but always set [brave://settings/system/shortcuts here] in all profiles.&lt;br /&gt;
&lt;br /&gt;
=== Settings ===&lt;br /&gt;
Immediately change these Settings on any new profile:&lt;br /&gt;
* Get started &amp;gt; Profile name and icon &amp;gt; customize it!&lt;br /&gt;
* Get started &amp;gt; New Tab Page &amp;gt; shows &amp;gt; Homepage&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Show home button ON, set to bitpost.com&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Brave Rewards, Brave Wallet, Sidebar &amp;gt; OFF&lt;br /&gt;
* Appearance &amp;gt; Toolbar &amp;gt; Show wide address bar, show full urls &amp;gt; ON&lt;br /&gt;
* Appearance &amp;gt; Sidebar &amp;gt; Show: never&lt;br /&gt;
* (NO) Appearance &amp;gt; Content &amp;gt; (very bottom) Cycle through the most recently used tabs with Ctrl-Tab&lt;br /&gt;
* Sync &amp;gt; I have a chain &amp;gt; paste, toggle Sync everything ON&lt;br /&gt;
&lt;br /&gt;
TODO: consider playing with vertical tabs!  It&#039;s a mindfuck tho...&lt;br /&gt;
&lt;br /&gt;
=== Profiles ===&lt;br /&gt;
Profiles in Brave are AWESOME:&lt;br /&gt;
* Brave seems to remember what desktop the windows were on!!!  FINALLY&lt;br /&gt;
* For each profile, you get a name and customizable icon in the top-right of the toolbar, SO NICE&lt;br /&gt;
* Bookmarks etc. are all profile-specific, as expected&lt;br /&gt;
* You can sync a profile across machines (see #Sync)&lt;br /&gt;
&lt;br /&gt;
==== Finding Profile folder ====&lt;br /&gt;
You can start brave with a specific profile, like this:&lt;br /&gt;
 brave-browser --profile-directory=&#039;Profile 4&#039;&amp;amp;&lt;br /&gt;
This is a bit dicey as the folder you must provide does not actually match the profile name!  I used this bit of ugliness to get a map of name to folder:&lt;br /&gt;
&lt;br /&gt;
  💉 m@cast  [~/.config/BraveSoftware/Brave-Browser] grep -Po &amp;quot;\&amp;quot;name\&amp;quot;:\&amp;quot;[^\&amp;quot;]*?\&amp;quot;,\&amp;quot;(pa|usi)&amp;quot; * -R&lt;br /&gt;
 Default/Preferences:&amp;quot;name&amp;quot;:&amp;quot;moodboom&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 4/Preferences:&amp;quot;name&amp;quot;:&amp;quot;es-1&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 5/Preferences:&amp;quot;name&amp;quot;:&amp;quot;mdmdev-1&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 6/Preferences:&amp;quot;name&amp;quot;:&amp;quot;Profile 2&amp;quot;,&amp;quot;pa&lt;br /&gt;
 Profile 7/Preferences:&amp;quot;name&amp;quot;:&amp;quot;ig-1&amp;quot;,&amp;quot;usi&lt;br /&gt;
&lt;br /&gt;
==== Assign VSCode Launch to (re)use a Brave profile ====&lt;br /&gt;
When vscode starts its Javascript debugger, it uses a custom &amp;quot;user-data-dir&amp;quot; within its own config folder.  This means you start with a clean profile upon first use.  However, (after MUCH trial-and-horror), you can specify that it uses a precise profile within this custom user-data-dir.&lt;br /&gt;
&lt;br /&gt;
If you use a launch.json stanza like this, vscode will always use that specific profile.  You can then start customizing the profile, and your changes will stick across debugging sessions.  Awesome!&lt;br /&gt;
  &amp;quot;configurations&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;Launch Brave&amp;quot;,&lt;br /&gt;
      &amp;quot;runtimeExecutable&amp;quot;: &amp;quot;/usr/bin/brave-browser&amp;quot;,&lt;br /&gt;
      // NOTE: This directory will be within .code/Code/User; specifying it allows reuse of a specific Profile there, nice.&lt;br /&gt;
      &amp;quot;runtimeArgs&amp;quot;: [ &amp;quot;--profile-directory=\&amp;quot;Profile 4\&amp;quot;&amp;quot; ],&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;chrome&amp;quot;,&lt;br /&gt;
      &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 5000,&lt;br /&gt;
      &amp;quot;url&amp;quot;: &amp;quot;http://localhost:8008&amp;quot;,&lt;br /&gt;
      &amp;quot;webRoot&amp;quot;: &amp;quot;${workspaceFolder}/src&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
&lt;br /&gt;
That should be all you need to get usage of a consistent profile across sessions.  But... say you want to sync it across development environments... why not!  Read on...&lt;br /&gt;
&lt;br /&gt;
===== More Details =====&lt;br /&gt;
Again, we dig to get a map of profile names to folders.  First, run the debugger, and look for the process and params:&lt;br /&gt;
 ps ax|grep -Po brave.*config/Code/User/workspaceStorage/.*?profile&lt;br /&gt;
From that, you can extract a user-data-dir:&lt;br /&gt;
 --user-data-dir=/home/m/development/config/common/home/m/.config/Code/User/workspaceStorage/436f0a4c50203656e625d634df9e0ca9/ms-vscode.js-debug/.profile&lt;br /&gt;
NOTE that it seems that each vscode project has its own workspaceStorage!  Which is pretty crazy.  That means every dev project can have its own set of profiles.&lt;br /&gt;
&lt;br /&gt;
From the user-data-dir folder, you can get a map of profile name to folder:&lt;br /&gt;
 cd #your-user-data-dir#&lt;br /&gt;
 grep -Po &amp;quot;\&amp;quot;name\&amp;quot;:\&amp;quot;[^\&amp;quot;]*?\&amp;quot;,\&amp;quot;(pa|usi)&amp;quot; * -R&lt;br /&gt;
    &amp;quot;Profile 4&amp;quot;/Preferences:&amp;quot;name&amp;quot;:&amp;quot;es-2&amp;quot;,&amp;quot;usi&lt;br /&gt;
&lt;br /&gt;
Now that you know what is where.... Just like with &amp;quot;normal&amp;quot; profiles, you can sync them across machines.&lt;br /&gt;
&lt;br /&gt;
=== Set up sync ===&lt;br /&gt;
Do this for each profile:&lt;br /&gt;
* Settings &amp;gt; Sync &amp;gt; Start a new Sync Chain &amp;gt; Computer &amp;gt; copy Sync Chain Code &amp;gt; save in private&lt;br /&gt;
* Make sure Sync everything is toggled ON&lt;br /&gt;
* You can now paste this chain into another computer to sync this profile there&lt;br /&gt;
&lt;br /&gt;
== Backup ==&lt;br /&gt;
Synced brave profiles are so valuable!  So much so that you might want to back up the data.&lt;br /&gt;
&lt;br /&gt;
This includes three major chunks of data, but you can only export two:&lt;br /&gt;
* Export passwords to a safe place, from here:&lt;br /&gt;
 Settings &amp;gt; Autofill and passwords &amp;gt; Password Manager &amp;gt; (left pane) Settings &amp;gt; Export passwords&lt;br /&gt;
* Export bookmarks from here:&lt;br /&gt;
 Main Menu (top-right hamburger) &amp;gt; Bookmarks &amp;gt; Bookmars Manager &amp;gt; More (top-right ...) &amp;gt; Export&lt;br /&gt;
* Autofill (Payment methods, Addresses)&lt;br /&gt;
 Settings &amp;gt; Autofill and passwords &amp;gt; Payment methods, Addresses (view-only, no export)&lt;br /&gt;
&lt;br /&gt;
== [https://brave.com/linux/ Install] ==&lt;br /&gt;
Copy and paste this all in one shot!&lt;br /&gt;
 sudo curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg&lt;br /&gt;
 echo &amp;quot;deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main&amp;quot;|sudo tee /etc/apt/sources.list.d/brave-browser-release.list&lt;br /&gt;
 sudo apt update&lt;br /&gt;
 sudo apt install brave-browser&lt;br /&gt;
&lt;br /&gt;
One annoying thing... the apt file searches all architectures and you&#039;ll get i386 errors, until you add &amp;quot;arch=amd64&amp;quot; like this:&lt;br /&gt;
 sudo emacs /etc/apt/sources.list.d/brave-browser-release.list&lt;br /&gt;
 &lt;br /&gt;
 deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg arch=amd64] https://brave-browser-apt-release.s3.brave.com/ stable main&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Profiles ===&lt;br /&gt;
At one point, maybe after a crash, my profiles stopped fully loading.  Passwords and history were not getting loaded.  I updated my system and rebooted and after a day or two of suffering they just came back on a reboot.  GOOD LORD I need them!  So... back them up...&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Workflowy&amp;diff=7899</id>
		<title>Workflowy</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Workflowy&amp;diff=7899"/>
		<updated>2025-12-27T16:33:59Z</updated>

		<summary type="html">&lt;p&gt;M: Created page with &amp;quot;Workflowy is a simple text tree.  Quickly add and remove items and move them around.  Remember to DO things and not just add things, lol.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Workflowy is a simple text tree.  Quickly add and remove items and move them around.&lt;br /&gt;
&lt;br /&gt;
Remember to DO things and not just add things, lol.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Kodi&amp;diff=7898</id>
		<title>Kodi</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Kodi&amp;diff=7898"/>
		<updated>2025-12-27T14:20:13Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;KODI IS LIFE&lt;br /&gt;
&lt;br /&gt;
=== Addons ===&lt;br /&gt;
&lt;br /&gt;
=== Tricks and Tips ===&lt;br /&gt;
&lt;br /&gt;
==== Ensure no tearing ====&lt;br /&gt;
&lt;br /&gt;
* Get nvidia-settings working right&lt;br /&gt;
** Ensure 4k, 60 fps&lt;br /&gt;
** TO KILL TEARING YOU MUST FORCE FULL COMPOSITION, it should be a setting under Screen &amp;gt; Advanced&lt;br /&gt;
&lt;br /&gt;
=== Configure ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Config files ====&lt;br /&gt;
See the flatpak config files here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data&lt;br /&gt;
&lt;br /&gt;
The log file is here:&lt;br /&gt;
 ~/.var/app/tv.kodi.Kodi/data/temp/kodi.log&lt;br /&gt;
&lt;br /&gt;
==== Startup ====&lt;br /&gt;
It should start up using this, on case:&lt;br /&gt;
 ~/scripts/ubuntu/case/start_my_apps.sh&lt;br /&gt;
&lt;br /&gt;
That runs&lt;br /&gt;
 /usr/bin/flatpak run tv.kodi.Kodi --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
Not sure that is working yet tbh...&lt;br /&gt;
&lt;br /&gt;
==== Audio ====&lt;br /&gt;
Flatpak kodi and root system audio are currently fubar.  Out-of-the-box will BREAK YOUR EARS, or worse, remain silent.  To fix it, hardcode pulseaudio with this option:&lt;br /&gt;
 --audio-backend=pulseaudio&lt;br /&gt;
&lt;br /&gt;
==== Media ====&lt;br /&gt;
Fucking flatpak knows nothing of the root filesystem.  Do this to grant it:&lt;br /&gt;
 sudo flatpak override --filesystem=host tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
If you want to fiddle with giving it less access, you can maybe try something like this but you may have to diddle the whole damned library...&lt;br /&gt;
 sudo flatpak override --reset tv.kodi.Kodi&lt;br /&gt;
 sudo flatpak override --filesystem=/spiceflow/media tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
Kodi has sadly chosen to go flatpak.&lt;br /&gt;
&lt;br /&gt;
 sudo apt purge kodi\*&lt;br /&gt;
 cd development/config/ubuntu/case/etc/apt/sources.list.d/&lt;br /&gt;
 git rm -f team-xbmc-ubuntu-ppa-noble.sources&lt;br /&gt;
 &lt;br /&gt;
 sudo apt install flatpak&lt;br /&gt;
 sudo apt install gnome-software-plugin-flatpak&lt;br /&gt;
 flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&lt;br /&gt;
 flatpak install flathub tv.kodi.Kodi&lt;br /&gt;
&lt;br /&gt;
==== Migration from apt to flatpak ====&lt;br /&gt;
&lt;br /&gt;
Copy config from apt to flatpak:&lt;br /&gt;
 cd ~/.var/app/tv.kodi/Kodi&lt;br /&gt;
 mv data data-orig&lt;br /&gt;
 cp -rp ~/.kodi directory to ~/.var/app/tv.kodi.Kodi&lt;br /&gt;
 mv .kodi data&lt;br /&gt;
 # NOT ~/.var/app/tv.kodi.Kodi/data/.kodi&lt;br /&gt;
 # YES ~/.var/app/tv.kodi.Kodi/data/userdata&lt;br /&gt;
 # NOT ~/var/app/tv.kodi.Kodi/data/.kodi/userdata&lt;br /&gt;
&lt;br /&gt;
=== HISTORY deprecated ===&lt;br /&gt;
&lt;br /&gt;
install&lt;br /&gt;
* First you must remove any old install:&lt;br /&gt;
 sudo apt remove --autoremove kodi&lt;br /&gt;
 sudo apt autoremove&lt;br /&gt;
* Add official kodi ppa: &lt;br /&gt;
 sudo add-apt-repository ppa:team-xbmc/ppa&lt;br /&gt;
* Install:&lt;br /&gt;
 sudo apt install kodi&lt;br /&gt;
&lt;br /&gt;
Upgrade&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt upgrade # as usual, once you have added the ppa (see Install)&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=Video_Editing&amp;diff=7897</id>
		<title>Video Editing</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=Video_Editing&amp;diff=7897"/>
		<updated>2025-12-16T15:37:52Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Create a Project folder:&lt;br /&gt;
 /spiceflow/projects/MyVideoProject&lt;br /&gt;
* Store your raw video there:&lt;br /&gt;
 /spiceflow/projects/MyVideoProject/source&lt;br /&gt;
* Play the raw video in [[VLC]] to vet it, as needed&lt;br /&gt;
* Trim and re-code the video in [[HandBrake]].  You should trim out all footage that will not be used in the end result.&lt;br /&gt;
** Play each video file in [[VLC]], and make note of the timestamp range(s) to keep.&lt;br /&gt;
** Choose a good encoding, like 1080pfast.&lt;br /&gt;
** Click Range: Seconds, and set timestamps for the range you want.&lt;br /&gt;
** Hit Start&lt;br /&gt;
** If there is more than one section in the video, repeat, changing the output name first so it is not overwritten, then the timestamp, then Start&lt;br /&gt;
** Move files&lt;br /&gt;
 mv ~/Video/* /spiceflow/projects/MyVideoProject/trimmed/&lt;br /&gt;
* [[Blender]] and [[Davinci Resolve]] both offer advanced video editing.  [[Blender]] is easier to set up and I&#039;m more familiar with it.  Need more time on both.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
	<entry>
		<id>https://bitpost.com/w/index.php?title=HandBrake&amp;diff=7896</id>
		<title>HandBrake</title>
		<link rel="alternate" type="text/html" href="https://bitpost.com/w/index.php?title=HandBrake&amp;diff=7896"/>
		<updated>2025-12-16T15:36:32Z</updated>

		<summary type="html">&lt;p&gt;M: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://handbrake.fr/ HandBrake] has been crushing video re-encoding for a long time.  Along with [[VLC]] you can probably handle any video on Earth.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Looks like the latest version is released as flatpak, oh well.&lt;/div&gt;</summary>
		<author><name>M</name></author>
	</entry>
</feed>