Working with git: Difference between revisions
Brian Wilson (talk | contribs) |
Brian Wilson (talk | contribs) |
||
Line 215: | Line 215: | ||
git clone [email protected]:brian32768/gt.git gt_dev2 | git clone [email protected]:brian32768/gt.git gt_dev2 | ||
cd gt_dev2 | cd gt_dev2 | ||
git checkout -b "dev" | git checkout -b "dev" origin/dev | ||
If I leave off the "origin/dev" then I don't get the branch "dev" from the remote, I get "master". | |||
It creates a new local branch called dev containing the code from master, wildly confusing me! | |||
When I did this I had to recover from it: <code>git checkout master && git branch -d dev && git checkout -b dev origin/dev</code> | |||
Now I can see my typo when I look at README.md so I know I am in the right place. | |||
vi README.md | vi README.md | ||
git commit -m "made a change at home" | git commit -m "made a change at home" | ||
Line 260: | Line 266: | ||
If I do change the (shared) style sheet for example, then I will have to do a more careful merge. | If I do change the (shared) style sheet for example, then I will have to do a more careful merge. | ||
==== Tags ==== | |||
In a working directory | |||
git tag -a 1.0 -m "First major release" | |||
git push origin 1.0 | |||
To check out this tagged version | |||
git clone [email protected]:brian32768/gt | |||
git checkout -b version1 1.0 | |||
You've basically now checked out an outdated or variant branch so be careful about merging new code and commiting, you'd have to move the tag forward or preferably use a new tag such as 1.0.1. | |||
== Git submodules == | == Git submodules == |
Revision as of 00:54, 8 November 2018
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
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]:contours.git
- cd ssurgo.git/
- 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: 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 on the laptop,
- Push changes to the git server,
- Pull the changes down into the live web server.
- Test live server. If the live server breaks after an update, I can revert the changes.
Alternatively, at step 3
- Move old content aside
- Clone a new copy onto the server
- This leaves old content available as a backup.
In either workflow, the content on the server should be marked read-only to avoid the temptation to 'dabble' and do little touch ups on the production server.
Use case: git for Asterisk server configuration
Each server needs tweaks to its configuration. When you are bending config files and something stops working you need to be able to back out the changes.
File ownerships and 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.
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
Branching and all it entails
You want to make changes that are in testing or development or a variant for release and you want to keep the changes separate forever (a variant branch) or until the feature under test is merged back into the trunk. That is what branching is for.
It's important to remember that Git is distributed so a branch can exist on your local machine and never touch the repository. The entire branch lifecycle can stay on your local hard drive if you don't need to share (or move between two computers the way I do every day).
I am (from now on) following "the Driessen model". Read this carefully, especially regarding feature branches, which I started using today. :-)
The excellent free Pro Git book on the Git site explains branching including getting rid of a branch and dealing with merge conflicts.
This explanation is also good for the nuts and bolts of merging. http://longair.net/blog/2009/04/16/git-fetch-and-merge/
Normal project workflow
This includes working SOLO, because the commits to master should always be considered as working code. If "dev" is not working, don't do merges to master!
Let's try all this out.
Create repo
I am using my personal github account "brian32768", you use your own. :-)
Create a new empty github project called "brian32768/gt". (I let it add README.md and LICENSE.txt) This creates the "master" aka trunk.
Create a local, working copy.
cd ~/source/repos git clone [email protected]:brian32768/gt.git cd gt
Create a development branch "dev".
git checkout -b dev
Show the branch we're on; there will be two now "dev" and "master". "git status" shows the branch, too.
git branch
Henceforth do all development and testing on "dev"
Edit the README.md
vi README.md
Add a new file.
vi index.html git add index.html
Stage the changes and push them up to github
git commit -m 'here we go a coding, ra ra ra' -a git push --set-upstream origin dev
(Just the usual "git push" is not good enough the first push, you have to use set-upstream to create the branch in the repo.)
If you look in github now you should see both "master" and "dev" branches. Master should be untouched at this time.
Work in two places at once
I should be able to go home, clone on Murre, move to the "dev" branch, and make changes there. (Or I could just chdir to a separate place on my work computer, to mimic this workflow. :-)
git clone [email protected]:brian32768/gt.git gt_dev2 cd gt_dev2 git checkout -b "dev" origin/dev
If I leave off the "origin/dev" then I don't get the branch "dev" from the remote, I get "master".
It creates a new local branch called dev containing the code from master, wildly confusing me!
When I did this I had to recover from it: git checkout master && git branch -d dev && git checkout -b dev origin/dev
Now I can see my typo when I look at README.md so I know I am in the right place.
vi README.md git commit -m "made a change at home" git push
Now back on computer #1 the following day I need to get any changes I made at home, since both working directories (at work and at home) are on the "dev" branch, this should work.
cd source/repos/gt git fetch
There should not be any changes on the branch to merge so no 'git merge' needed here.
Now check contents of README.md to make sure the change came in correctly.
Merge dev changes back into master
When you think you have working code, you must merge dev changes back into master.
For the purposes of my test, let's say that the recent change was wrong and I want to revert master to the previous version.
Now I am back at the previous version in master. I can leave things this way indefinitely while I deal with the issue in "dev", or I can do the same thing in "dev" - revert to the previous version to get rid of the broken changes. In this demo I just push ahead.
So I fix "dev". Then, I check in the changes on "dev" and merge to master again. This time the change is fine.
Feature branching
"Dev" is just the normal day to day stuff, and when I create a feature branch it's off of "dev". When I create a branch to support a specific production version that uses different assets (for example special branding), that's branched directly off "master".
Working with variants
The other use case I want to test is how to work with a variant branch; in this case, I want to create two different web sites with different branding.
To test this, I add the generic "map46.svg" and accompanying CSS style sheet to the master.
I create the variant branch and add a Clatsop County ""cclogo.gif" logo there with a different style sheet that will insert this graphic.
Now the question is, how do I support both? I make a change to "dev", merge it back to master, and then I have to merge changes from master to variant without stepping on the assets. Since the assets did not change on master, this should be no problem.
If I do change the (shared) style sheet for example, then I will have to do a more careful merge.
Tags
In a working directory
git tag -a 1.0 -m "First major release" git push origin 1.0
To check out this tagged version
git clone [email protected]:brian32768/gt git checkout -b version1 1.0
You've basically now checked out an outdated or variant branch so be careful about merging new code and commiting, you'd have to move the tag forward or preferably use a new tag such as 1.0.1.
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! 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.