Git

From Bitpost wiki
Revision as of 18:52, 28 May 2019 by M (talk | contribs)

TASKS

git new shared central bare repo
On central server (aka bitpost):
cd development(...)
git init --bare --shared mynewthang.git

On development box

cd development(...)
git clone bitpost.com:development/mynewthang.git
# this will create a new empty repo with no branch yet
# create files, then use git to add them, commit them and push them
# that will create remote-tracked master branch for you

Back on bitpost

git clone mynewthang.git # to create a working copy on server, if desired
create shared central repo for existing code
Create a bare repo with .git suffix
git init --bare --shared mything.git

Go to existing code and clone the repo next to it, with a temp name. Move .git into the existing code. Add code, add a .gitignore as needed, and you're all set.

cd mything/..
git clone (bare-repo-host-and-path)mything.git mything-temp
mv mything-temp/.git mything/
rm -rf mything-temp
cd mything
subl .gitignore # as needed
git add (whatever you want to track)
git commit -a -m "init repo" && git push
git merging conflicts after diverging
Revert local changes in a file to HEAD
git checkout -- path/to/file.txt

Discard ALL LOCAL COMMITS and get the (possibly diverged) remote instead

git reset --hard origin/master
git create and push a feature branch
This will move recent commits AND uncommitted changes into a new branch (but you probably want to finish by cleaning out commits from starting branch, and repulling after you merge the feature).
git checkout -b feature/whiz-bang
git push -u origin feature/whiz-bang
# OR, do this ONCE: git config --global push.default current
# Then:
git push -u
getting upstream commits into your GitHub fork
From so...

Add the remote, call it something specific:

git remote add someauthor-upstream https://github.com/someauthor/theprojectiforked.git

Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:

git fetch someauthor-upstream

Get on the branch where you are tracking the rebase. Typically your master branch but can be whatever:

git checkout tlsv12 # or master or next or...

Rewrite your branch so that any commits of yours that aren't already in upstream are replayed on top of that other branch (if you do a straight merge instead of rebase you'll screw up the upstream!):

git rebase someauthor-upstream/master

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've rebased:

git push -f origin master

ELSE if the branch you merged into is a new creation, set its upstream when you push:

git push --set-upstream origin tlsv12
git create new branch on server, pull to client
# ON CENTRAL SERVER
git checkout master # as needed; we are assuming that master is clean enough as a starting point
git checkout -b mynewbranchy

# HOWEVER, use this instead if you need a new "clean" repo and even master is dirty...
# You need the rm because git "leaves your working folder intact".
git checkout --orphan mynewbranchy
git rm -rf .

# ON CLIENT
git pull
git checkout -b mynewbranchy origin/mynewbranchy
# if files are in the way from the previously checked-out branch, you can force it...
git checkout -f -b mynewbranchy origin/mynewbranchy
git remove old branches
Explanation is here.

Remote:

git push origin --delete <branch>

Local:

git branch -d <branch>
git fetch <remote> --prune # Delete multiple obsolete tracking branches
Work with two local repos
Set up a remote, then fetch it as master.
cd repoToChange
git remote add otherplace ../../wherever/../gitrepo
git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)
git fetch otherplace # gets it all
git checkout --track otherplace/master # or other branch as needed; this creates the branch and sets remote in one step, cool

Set up a remote, then fetch it into a non-master branch, and push it to the active origin.

cd repoToChange
git remote add otherplace ../../wherever/../gitrepo
git ls-remote otherplace # verify it looks ok, figure out which branch you like (if not master)
git fetch otherplace # gets it all
git checkout otherplace/master # creates it detached, good because we need to name the new branch something other than master
git checkout -b new_otherplace_branchname # creates new local branch with a good name
git push --set-upstream origin new_otherplace_branchname # takes the branch from the OLD origin and pushes it to the ACTIVE origin, cool!
git pull when untracked files are in the way
This will pull, forcing untracked files to be overwritten by newly tracked ones in the repo:
git fetch --all
git reset --hard origin/mymatchingbranch
git create new branch when untracked files are in the way
  git checkout -b bj143 origin/bj143
     git : error: The following untracked working tree files would be overwritten by checkout:
     (etc)
  
  TOTAL PURGE FIX (too much):
     git clean  -d  -fn ""
        -d dirs too
        -f force, required
        -x include ignored files (don't use this)
        -n dry run
  
  BEST FIX (just overwrite what is in the way):
     git checkout -f -b bj143 origin/bj143
git recreate repo
git clone ssh://m@thedigitalmachine.com/home/m/development/thedigitalage/ampache-with-hangthedj-module
cd ampache-with-hangthedj-module
git checkout -b daily_grind origin/daily_grind

If you already have the daily_grind branches and just need to connect them:

git branch -u origin/daily_grind daily_grind
git connect to origin after the fact
git remote add origin ssh:// m@bitpost.com/home/m/development/logs
git fetch
    From ssh:// bitpost/home/m/development/logs
     * [new branch]      daily_grind -> origin/daily_grind
     * [new branch]      master     -> origin/master
git branch -u origin/daily_grind daily_grind
git checkout master
git branch -u origin/master master
git ignore local and remote changes to a file
This is helpful for conf files that need local-specific modifications that shouldn't be pushed. You have to toggle it on/off as needed to get updates! See my SO answer.
       PREVENT COMMIT OF CHANGES TO A LOCAL FILE
       -----------------------------------------
       git update-index --skip-worktree apps/views/_partials/jsIncludes.scala.html

       RESET TO GET CHANGES AGAIN
       --------------------------
       git update-index --no-skip-worktree apps/views/_partials/jsIncludes.scala.html

       LIST SKIPPED FILES
       ------------------
       git ls-files -v . | grep ^S
       S app/views/_partials/jsIncludes.scala.html
       -----------------------------------------
git branch rebase to keep master intact
Basically you want to rebase your branch using master. Simple enough, devil in the details. You should maintain a clean master branch that can be updated at any time, and a branch for your custom work that can be rebased at any time.

Example:

       # on other: update the master branch with other users' changes
       # on gold:
       git checkout master && git pull # should always be a ff
       git checkout US290016
       git rebase -i master # you'll possibly get merge conflicts
           git mergetool # fix it up - this will show you REMOTE head, LOCAL head, and BASE common ancestor
           git rebase --continue # AHA this will tell you you are only partially through, see the commit #comments for details
           git push --force # AHA this fails if remote does not allow it!
               # change remote config, if you get: remote: error: denying non-fast-forward refs/heads/US290016
               # then you need to go to remote and change config
               # see https://stackoverflow.com/questions/10544139/how-to-force-push-a-reset-to-remote-repository
               git config receive.denynonfastforwards false
       # on other: reset US290016
       # reset to the commit for the last known base ancestor (or earlier, doesn't hurt)
       git reset --hard 96ba297
       git pull --rebase # rebase should not be needed, it should be a ff, but just in case use it
git changing branches in a project with submodules
# always reset the @*$ submodules to proper commits
git checkout develop && git submodule update
git hard-reset a misbehaving submodule to parent commit version
git submodule deinit -f .
git submodule update --init

CONFIGURATION

git visual difftool and mergetool setup
Meld is purdy, let's kick its tires. Hope it actually works...
git config --global diff.tool meld
git config --global merge.tool meld
git config --global --add difftool.prompt false

I used to set up kdiff3 manually, like this... (gross)

  • LINUX - put this in ~/.gitconfig
[diff]
    tool = kdiff3

[merge]
    tool = kdiff3
  • WINDOZE
[difftool "kdiff3"]
    path = C:/Progra~1/KDiff3/kdiff3.exe
    trustExitCode = false
[difftool]
    prompt = false
[diff]
    tool = kdiff3
[mergetool "kdiff3"]
    path = C:/Progra~1/KDiff3/kdiff3.exe
    trustExitCode = false
[mergetool]
    keepBackup = false
[merge]
    tool = kdiff3
  • LINUX Before - What a ridiculous pita... copy this into .git/config...
[difftool "kdiff3"]
    path = /usr/bin/kdiff3
    trustExitCode = false
[difftool]
    prompt = false
[diff]
    tool = kdiff3
[mergetool "kdiff3"]
    path = /usr/bin/kdiff3
    trustExitCode = false
[mergetool]
    keepBackup = false
[merge]
    tool = kdiff3
git convert to a bare repo
Start with a normal git repo via [git init]; add your files, get it all set up. Then do this:
cd repo

Now you can copy-paste this...

mv .git .. && rm -fr *
mv ../.git .
mv .git/* .
rmdir .git
git config --bool core.bare true
cd ..

Don't copy/paste these, you need to change repo name...

mv repo repo.git # rename it for clarity
git clone repo.git # (optional, if you want a live repo on the server where you have the bare repo)

Then you can clean up old branches like daily and daily_grind, as needed.

git convert bare to a mirror of remote (github, facebook, etc)
You need a bare mirror repo if you want to take someone else's repo and create your own bare to work from.

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:

[remote "origin"]
   url = git@github.com:facebook/proxygen.git
   fetch = +refs/*:refs/*
   mirror = true

Now you can fetch from the bare repo:

git fetch
git create merge-to command
Add this handy alias command to all git repos' .config file...
[alias]
    merge-to = "!gitmergeto() { export tmp_branch=`git branch | grep '* ' | tr -d '* '` && git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset tmp_branch; }; gitmergeto"

git fix github diverge from local bare repo following README.md edit
Yes editing the README.md file on github will FUCK UP your downstream bare repo if you meanwhile push to it before pulling.

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...

git clone git@github.com:moodboom/quick-http.git quick-http-with-readme-conflict
git remote add local ../quick-http
git fetch local
git merge local/master # merge in changes, likely trivial
git push # pushes back to github
cd ..
mv quick-http.git quick-http.git__gone-out-of-sync-fu-github-readme-editor
git clone git@github.com:moodboom/quick-http.git --bare
cp quick-http.git__gone-out-of-sync-fu-github-readme-editor/config quick-http.git/

And that MIGHT get you on your way... but I would no longer trust ANY of your local repos... This is a serious pita.

git windows configure notepad++ editor
git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
git fix push behavior - ONLY PUSH CURRENT doh
git config --global push.default current
git multiple upstreams
Use this to cause AUTOMATIC push/pull to a second origin:
git remote set-url origin --push --add user1@repo1
git remote set-url origin --push --add user2@repo2
git remote -v show

Leave out --push if you want to pull as well... but I'd be careful, it'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.


From here... Git for nice release planning.png