Coder Social home page Coder Social logo

git-private's Introduction

git-private-push

Create a hidden branch in remote repositories.

Use git private-push to backup your work-in-progress branches, to keep history when frequently rebasing a branch without cluttering everyone's view, or to let others know the branch may get rebased at any time.

gitk will display these refs in a nice gray color.

WARNING: Hidden branches offer absolutely no security or privacy. They are just neither displayed nor fetched by default.

Features

  • multiple private spaces
  • pushing multiple configured refs by single command (private.*.push)
  • automatic timestamping (private.*.tsfmt)
  • automatic force push (private.*.force)
  • customizable remote refs ($USER, $EMAIL, $TS and $DST are recognized)

Missing features

  • man page! Sorry. git private-push --help will not work until a man page is added. Use git-private-push --help instead.

Internals

Git by default fetches from refs/heads/, refs/tags/. Pushing to a non-default subdirectory in refs will create a "hidden" branch which is not fetched unless asked for.

Installation

Requirements

  • git
  • bash

How to install

  1. Get the git-private-push and git-private-add-fetch scripts, by either:
    • Cloning this repository:
      git clone https://github.com/csonto/git-private.git
    • Downloading the zip archive and extracting it locally:
      wget https://github.com/csonto/git-private/archive/master.zip && unzip master.zip
  2. Make the script callable form anywhere on your system, by either:
    • Adding the script files to a directory in your $PATH, e.g.:
      cp <path/to/git-private>/git-private-* /usr/local/bin/
    • Creating a link to the script files from such a directory, e.g.:
      ln -s <path/to/git-private>/git-private-push /usr/local/bin/git-private-push
    • Adding the directory where you downloaded the files to your $PATH, e.g.:
      echo 'export PATH="<path/to/git-private>:$PATH"' >> ~/.bashrc && source ~/.bashrc

Usage

Configure private branches

First, basic configuration of private branches.

By default "junk" space is used. This default can be changed by changing private.id config option.

By default each private space uses remote with the same name. For the default "junk" space you either need to create the remote:

git remote add junk $URL

Or change remote option like this:

git config private.junk.remote origin

You can also change the default remote for git working directory:

git config private.remote origin

Or change global default:

git config --global private.remote origin

See more bellow at Configuration. And have a look at Examples.

Pushing

The git private-push is used as follows:

git private-push [--id ID] [--force|--no-force] [BRANCH [DESTINATION]]

Push to the default private space, named "junk":

git private-push master

Push a ref from remote to a private space named "wip", with custom destination:

git private-push --id wip remotes/local/master local

Fetching

Add fetch config options to private "remote":

git config --add remote.$remote.fetch "+refs/$path/*:refs/$path/$remote/*"

e.g. for the private space named wip at the origin remote:

git config --add remote.origin.fetch "+refs/wip/*:refs/wip/origin/*"

Or use git-private-add-fetch [ID].

Concrete examples

By default .git/config contains something like this:

[remote "origin"]
    url = [email protected]:csonto/git-private.git
    # This is the default:
    fetch = +refs/heads/*:refs/remotes/origin/*

The directory structure is up to you. In general you will likely want to follow up git's refs/$PATH/$REMOTE pattern. To fetch all refs from the remote add a line like this:

    fetch = +refs/*:refs/all/origin/*

To fetch a subdirectory from the remote, add a line like this:

    fetch = +refs/wip/csonto/*:refs/wip/csonto/*

Common options should go to ~/.gitconfig, and project-specific options to $PROJECT/.git/config.

Let's see something more useful...

Backup

I want a copy of my work stored on the server. I do not require history, single copy is good enough for me.

git wip
git wip BRANCH

Eventually I might want to push uncommitted changes:

git stash
git wip "stash@{0}" stashed
git stash pop

If you want this to work for all your git repos, add a common configuration to ~/.gitconfig:

[private "wip"]
    # anything will do, timestamps are not used:
    tsfmt = "-"
    # ignoring TS, wip is not tracking history, only latest change is pushed:
    fmt = "$EMAIL/$DST"
    # the wip refs will be rewritten so push has to be forced:
    force = 1

[alias]
    wip = private-push --id wip

Add a project specific part - remote, list of branches - to project's .git/config.

For each branch to store run:

git config --add private.wip.push BRANCH

To use different remote for this project add:

git config private.wip.remote REMOTE

The configuration will look like this (without comments):

[private "wip"]
    # by default remote with same name (thus "wip") will be used.
    # You can use your own git server for backups:
    #remote = private

    # refs to backup with git wip:
    push = master
    push = gh-pages
    # add more here...

Now you could do git wip and it will push the listed refs (master and gh-pages) to refs/wip/[email protected]/BRANCH (refs/wip/[email protected]/master and refs/wip/[email protected]/gh-pages.)

Anything what is in your refs can be pushed, if you have another remote (local) set up, remote heads can be pushed like this:

git config --add private.wip.push remotes/local/master

If you want to keep the refs short use different name:

git config --add private.wip.push "remotes/local/master local"

To automatically push the most recent stashed changes run:

git config --add private.wip.push "stash@{0} stashed"

To fetch them all:

git config --add remote.origin.fetch "+refs/wip/*:refs/wip/*"

To fetch only yours:

git config --add remote.origin.fetch "fetch = +refs/wip/[email protected]/*:refs/wip/*"

Well, that's it. Except, backup without history, is not a real backup. Let's add history...

Backup with history

I am working on a feature branch and I need to rebase frequently.

I want a copy of my work stored on the server and I want to have full history of changes if I need to go back after a bad rebase.

git backup BRANCH
git backup

Let's add the configuration:

[private "backup"]
    tsfmt = "%Y%m%d-%H%M"
    fmt = "$EMAIL/$DST/$TS"

[alias]
    backup = private-push --id backup

Add refs to backup by default:

git config --add private.wip.push wip

Now running git backup will push wip branch as refs/backup/[email protected]/wip/20160310-1135.

Hooray!

Configuration

  • private.$ID.* - configuration for particular private space
  • private.* - default options

It may be useful to define global defaults:

git config --global private.tsfmt "%Y/%m/%d/%H%M/"

The configuration options are:

  • private.id - default ID.
  • *.fmt - path format. Defaults to $TS$DST. Strings $TS, $USER, $EMAIL and SDST are replaced with corresponding values. These strings are replaced in $TS but not in any other of the values.
  • *.tsfmt - timestamp format. This defaults to %Y/%m/%d/%H/.
  • *.path - path within remote. This defaults to $ID/.
  • *.remote - remote where private refs are kept. Defaults to $ID.
  • *.push - SRC [DST] couple to use when not given on command line. There may be multiple of them.
  • *.force - if not empty force push if remote ref already exists. This may be overridden on command line by --no-force option.

For example to define origin for "WIP" space one can use:

git config private.wip.remote origin

Add a default push "pair" (using default destination):

git config --add private.wip.push master

Add a default push "pair" (using different destination):

git config --add private.wip.push "stash@{0} stashed"

In the .git/config it looks like:

[private "wip"]
remote = origin
path = wip/nb1/
tsfmt = 0/ # Use constant. Default would be used if empty.
push = master
push = "stash@{0} stashed"

[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/wip/*:refs/wip/origin/*

git-private's People

Contributors

csonto avatar waldyrious avatar

Watchers

James Cloos avatar 办公室 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.