Working with git
Overview
Most work I do is out on github in public repos that anyone can access, search for geo-ceg and brian32768. I can't put every bit of my life out on the Internet, so I still operate my own Git server for proprietary projects. I also work in other peoples' servers for projects.
This page contains notes both on Github and on using private Git servers.
I found that chapter 3 of the book "Building Enterprise JavaScript Applications" contains a pretty succinct introduction to git.
Git commands that I use most often
The main ones, obviously: init, clone, add, commit, status, push, pull*
- the ones everyone SHOULD use: fetch and merge instead of pull
The ones I forget about: log
Until today I never bothered with branches (missing half the fun!) because 99.9% of the time right now I work on code by myself. This is a stupid excuse since it means having a broken master branch on Github most of the time as I do nightly checkpoints to switch between home and work. So, read the section below on branches.
I should do more tagging.
Recovering from staging a file by accident:
git add oops.cs git reset HEAD oops.cs
"Master" controversy
2020-06 - people think that a branch in github called "master" is offensive, because it has something to do with slavery. This is, in my opinion, just ignorance. Many words have multiple meanings and in this cases, "master" refers to "an original from which copies are made." Other inoffensive uses including "being the master of your own fate", obtaining "a master's degree", and "mastering" github.
Whatever. I have been moving towards having two main branches on my repositories so I don't see it as a problem to use "release" instead of "master" to indicate code that should be usable and "dev" as the branch that might or might not work at any given time. It will help me be more organized. Over time I will migrate my repos to this set up but it's not a personal priority.
Changing "master" to "release"
These instructions I found on Stack Overflow and modified to suit my own use.
git commit -m "Commit any pending changes." -a git push git checkout -b release master # create and switch to the release branch git push -u origin release # push the release branch to the remote and track it git branch -d master # delete local master Go to the repository at https://github.com/ and bring up the Settings page. Go to Branches and make "Release" the main branch. git push --delete origin master # delete remote master git remote prune origin # delete the remote tracking branch git checkout -b dev Get on with life.
Migrating git projects to Github.com
I have migrated most of my shareable projects to github.com to get them off my own server, making them more accessible and creating an off-site backup at no cost to me. Pretty much all the same git commands below work.
Migration: Use the Github Importer.
I used the command line import method. Basically you pull the repo with all its history onto your local machine then push it up to github. In brief
- Create the repository first at github, "ssurgo" in this case.
- Make a copy of your existing repo: git clone --bare [email protected]:ssurgo.git
- cd ssurgo
- Push everything up to github: git push --mirror https://github.com/geo-ceg/ssurgo.git
- cd ..
- Make sure it worked by cloning it! git clone [email protected]:Geo-CEG/ssurgo.git
- If it worked you have a directory "ssurgo" now. Remove the bare repo: rm -rf ssurgo.git
- Try commiting by making a README. emacs README.me
- git add README.md
- git commit -a -m "added README!"
- git push
Use case: you moved a repo from a personal account to an organization account
You can do that on github.com but now you need to change the repo, actually you don't have to but it's tidier.*
git remote set-url origin newurl
- If you don't change it, github leaves a link behind to redirect things and it will all be fine.
Use case: git for web app development
One of the main reasons I want my own git server is so that I can sync a web app between my laptop and a server.
Work flow:
- Develop and test test test on the laptop, in the "dev" branch (or in a "feature" branch").
- When you think it's flawless, push changes to the git server, still on the "dev" branch.
- On the web server, move onto the dev branch and pull the changes down.
- Test live server. If the live server breaks after an update, switch back to "release" and pull to revert.
- After confirming web site is working, merge changes into "release", tag, and push.
- On web server, pull release down to update it.
Running a git server
File ownerships and ssh access control
Access to the server is through ssh. The repositories will be owned by the user 'git'. So I put the home for user 'git' where I want the repositories to be; on Bellman I use /green/repositories. Then I set up ssh with keys so that I don't need to share passwords.
I put create a separate 'git' key pair and put the public key into ~git/.ssh/authorized_keys I can test it with "ssh [email protected] list", this should list the available repos and exit.
Once that's all in place I don't need a complete path for the "remote" command, just one relative to git's home.
Here is how I generate a key for github
ssh-keygen -t rsa -b 4096 -C my_email_address eval $(ssh-agent -s) ssh-add ~/.ssh/id_rsa_github
Here is a quick way to test it
ssh [email protected] . . . Hi brian32768! You've successfully authenticated, but GitHub does not provide shell access.
Creating a new private repo
See also: http://www.git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server
I am using ssh for file transfer.
I find it easiest to create a new empty repo directly on the server and then push existing content into it.
ssh bellman cd ~git sudo git init --bare myproject.git create a bare repository sudo chown -R git.wildsong myproject.git exit cd source/repos assuming myproject is a folder containing the files you want in a repo cd myproject git init make a gitignore file in myproject git add some files git commit -m 'initial commit' git remote add origin [email protected]:myproject.git git push origin master this pushes committed files from the local repository to the master branch on the remote machine
Now I should be able to clone my project onto the web server and start using git to keep it updated.
ssh webserver cd /var/www/appserver git clone git.wildsong.biz:myproject.git
On my copy I need to define the remote repo,
git remote add origin [email protected]:myproject.git
When I make changes on the local laptop, first I commit them locally.
git commit
..then I push them up to the git server
git push origin master
..then I pull them down onto the public web server
git fetch
Then I create a virtualenv and load the requirements.
cd myproject virtualenv env source env/bin/activate pip install -r requirements.txt python run.py
Github collaboration
Now I want to contribute to someone's project. This description is good especially after reading the comments section too.
http://blog.davidecoppola.com/2016/11/howto-contribute-to-open-source-project-on-github/
Briefly, leaving out some critical steps...
- Fork -- Makes a copy of the project in Github that I can change
- Clone -- Pull the code down from Github to my computer
- Branch -- I will work in a branch and then remove it when done
- Edit -- Make proposed changes
- Issue pull request -- Notifies project owner; hopefully it will be accepted
Git submodules
I keep some code in github, and I want to incorporate it into a project. I can use the submodule feature.
cd myproject git submodule add [email protected]:brian32768/pyst2.git
This clones pyst2 into a subdirectory (called pyst2 by default) Now I can work on pyst2 and do commits and pushes but it remains separate from 'myproject'. If I ask for status...
git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage)
modified: .gitmodules new file: pyst2
If I am in a virtualenv then I can cd into pyst2 and do 'python setup.py install' and the right thing will happen.
When you clone a new copy or update an existing clone (git pull) then the submodules will be there but empty, you have do do this
cd pyst2 (or whatever your submodule folder is) git submodule init git submodule update
That will tell git to populate the submodule folder with code from the other repository.
Git in Docker
Docker mania! I have not tried doing this yet. This would be to replace the service installed on the host (Bellman). Not the client.
This one looks good. It is built on alpine and it has support for keys and data in volumes. Should drop right in on Bellman and replace the system level version.