writing custom git commands

DESCRIPTION

Creates an archive of the specified format containing the tree structure for the named tree, and writes it out to the standard output. If <prefix> is specified it is prepended to the filenames in the archive.

git archive behaves differently when given a tree ID versus when given a commit ID or tag ID. In the first case the current time is used as the modification time of each file in the archive. In the latter case the commit time as recorded in the referenced commit object is used instead. Additionally the commit ID is stored in a global extended pax header if the tar format is used; it can be extracted using git get-tar-commit-id. In ZIP files it is stored as a file comment.

OPTIONS

Format of the resulting archive: tar or zip. If this option is not given, and the output file is specified, the format is inferred from the filename if possible (e.g. writing to “foo.zip” makes the output to be in the zip format). Otherwise the output format is tar .

Show all available formats.

Report progress to stderr.

Prepend <prefix>/ to each filename in the archive.

-o <file> –output=<file>

Write the archive to <file> instead of stdout.

Look for attributes in .gitattributes files in the working tree as well (see ATTRIBUTES ).

This can be any options that the archiver backend understands. See next section.

Instead of making a tar archive from the local repository, retrieve a tar archive from a remote repository. Note that the remote repository may place restrictions on which sha1 expressions may be allowed in <tree-ish>. See git-upload-archive[1] for details.

Used with –remote to specify the path to the git-upload-archive on the remote side.

The tree or commit to produce an archive for.

Without an optional path parameter, all files and subdirectories of the current working directory are included in the archive. If one or more paths are specified, only these are included.

BACKEND EXTRA OPTIONS

zip

Store the files instead of deflating them.

Highest and slowest compression level. You can specify any number from 1 to 9 to adjust compression speed and ratio.

CONFIGURATION

This variable can be used to restrict the permission bits of tar archive entries. The default is 0002, which turns off the world write bit. The special value “user” indicates that the archiving user’s umask will be used instead. See umask(2) for details. If –remote is used then only the configuration of the remote repository takes effect.

This variable specifies a shell command through which the tar output generated by git archive should be piped. The command is executed using the shell with the generated tar file on its standard input, and should produce the final output on its standard output. Any compression-level options will be passed to the command (e.g. “-9”). An output file with the same extension as <format> will be use this format if no other format is given.

The “tar.gz” and “tgz” formats are defined automatically and default to gzip -cn. You may override them with custom commands.

If true, enable <format> for use by remote clients via git-upload-archive[1]. Defaults to false for user-defined formats, but true for the “tar.gz” and “tgz” formats.

ATTRIBUTES

Files and directories with the attribute export-ignore won’t be added to archive files. See gitattributes[5] for details.

If the attribute export-subst is set for a file then Git will expand several placeholders when adding this file to an archive. See gitattributes[5] for details.

Note that attributes are by default taken from the .gitattributes files in the tree that is being archived. If you want to tweak the way the output is generated after the fact (e.g. you committed without adding an appropriate export-ignore in its .gitattributes ), adjust the checked out .gitattributes file as necessary and use –worktree-attributes option. Alternatively you can keep necessary attributes that should apply while archiving any tree in your $GIT_DIR/info/attributes file.

EXAMPLES

git archive –format=tar –prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)

Create a tar archive that contains the contents of the latest commit on the current branch, and extract it in the /var/tmp/junk directory.

git archive –format=tar –prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz

Create a compressed tarball for v1.4.0 release.

git archive –format=tar.gz –prefix=git-1.4.0/ v1.4.0 >git-1.4.0.tar.gz

Same as above, but using the builtin tar.gz handling.

git archive –prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0

Same as above, but the format is inferred from the output file.

git archive –format=tar –prefix=git-1.4.0/ v1.4.0^ | gzip >git-1.4.0.tar.gz

Create a compressed tarball for v1.4.0 release, but without a global extended pax header.

git archive –format=zip –prefix=git-docs/ HEAD:Documentation/ > git-1.4.0-docs.zip

Put everything in the current head’s Documentation/ directory into git-1.4.0-docs.zip. with the prefix git-docs/ .

git archive -o latest.zip HEAD

Create a Zip archive that contains the contents of the latest commit on the current branch. Note that the output format is inferred by the extension of the output file.

git config tar.tar.xz.command “xz -c”

Configure a “tar.xz” format for making LZMA-compressed tarfiles. You can use it specifying –format=tar.xz. or by creating an output file like -o foo.tar.xz .

SEE ALSO

Writing Custom Commands for DNX with ASP.NET 5.0

If you are a developer on the .NET stack, you’ve now got access to a great new extension to your development environment. DNX, or the .NET Execution Environment, is a powerful new extensibility point that you can leverage to build project extensions, cross-platform utilities, build-time extensions and support for automation. In this article I’ll walk you through the process of building your own custom DNX command on top of ASP.NET 5.0.

Where You’ve Seen It

DNX has the ability to scan a project.json and look for commands that you install as packages or that you create yourself. If you’ve started following the examples of the MVC Framework or perhaps with Entity Framework, you may have seen things like this in your project.json:

[![image](https://jcblogimages.blob.core.windows.net/img/2015/08/image_thumb2.png “image”)](https://jcblogimages.blob.core.windows.net/img/2015/08/image5.png)These entries are here so that DNX understands the alias you assign (such as “web” or “ef”) and how it maps to an assembly that you’ve created or taken on as a dependency. The EF reference is quite straightforward above, simply saying that any call to “ef” via DNX will go into the entry point in EntityFramework.Commands. You would invoke that as follows from the directory of your _project_: All parameters that are passed in are available to you as well, so if you were to instead use: Then EF would be getting the params “help migrations” to parse and process. As can be clearly seen in the “web” alias, you can also specify defaults that get passed into the command when it is executed, thus, the call to web in the above project.json passes in the path and filename of the configuration file to be used when starting IIS express. There is no special meaning to “ef” or “web”. These are just names that you assign so that the correct mapping can be made. If you changed “ef” to “right-said-fred” you would be able to run migrations from the command line like so: Great! So you can create commands, pass in parameters and share these commands through the project.json file. But now what? ## Now What? I’m so glad you asked! So far things really aren’t too different from any other console app you might create. I mean, you can parse args and do whatever you like in those apps as well. But here’s the winner-winner-chicken-dinner bits: did you notice the “.” that is passed into DNX? That is actually the path to the project.json file, and this is important. *Important Note*: From beta 7 onward (or already if you’re on the nightly builds) DNX will implicitly run with an appbase of the current directory, removing the need for the “.” in the command. I’ll try to remember to come back to this post to correct that when beta 7 is out in the wild. Read more about the change on the [ASP.NET Announcement repo](https://github.com/aspnet/Announcements/issues/52) on GitHub. DNX doesn’t actually do a lot on its own, not other than providing an execution context under which you can run your commands. But this is a good thing! By passing in the path to a project.json, you feed DNX the command mappings that you want to use, and in turn, DNX provides you with all of the benefits of running inside of the ASP.NET 5.0 bits. Your console app just got access to Dependency Injection as a first-class citizen in your project, with access to information about whichever app it was that contained that project.json file. Consider the EF command mapping again for migrations for a second: what is going on when you tell it to add a migration? It goes something like this: 1. DNX looks for the project.json at the path you provide 2. It parses the project.json file and finds the command mapping associated with your statement 3. I **_creates an instance_** of the class that contains your command, injecting environment and project information as is available 4. It checks the rest of what you’ve passed in, and invokes the command, passing in any parameters that you’ve supplied ## How to Build Your Own This is actually super easy! Here’s what you need to do: 1. Create a new ASP.NET 5 Console Application in Visual Studio 2015 2. Add any services interfaces you need as parameters to the constructor of the Program class – but this is optional in the “hello dnx” realm of requirements 3. Add your logic to your Main method – start with something as simple as a Console.WriteLine statement From there, you can drop to a command line and run your command. That’s it! *Pro Tip* You can easily get a command line in your project folder by right-clicking on the project in Solution Explorer and selecting “Open Folder in File Explorer”. When File Explorer opens, simply type in “cmd” or “powershell” in the location bar and you’ll get your shell. The secret as to why it works from the console can be found in your project.json: when you create a console app from the project templates, the command alias mapping for your project is automatically added to your project. In this same way, along with referencing your new command project, _other projects_ can now consume your command. ## Beyond Hello World It is far more likely that you’re going to need to do something in the context of the project which uses your command. Minimally, you’re likely going to need some configuration drawn in as a default or as a parameter in your command. Let’s look at how you would take that hello world app you created in three steps and do something a little more meaningful with it. First, let’s add some dependencies to your project.json: Now let’s add a new JSON file to our project called config.json with the following contents: Getting there. Next, let’s bulk up the constructor of the Program class, add a private member and a Configuration property: We also need to add a method to Program that handles loading the config, taking in what it can from the config file, but loading on top of that any arguments passed in from the console: Finally, we’ll add a little more meat to our our Main method: The above sample can now be executed as a command. I’ve got the following command mapping in my project.json file (yes, the same project you use to create the command can also expose the command):

This means that from the console in the dir of my project I can just type in the following:

I can also now reference this project from any other project (or push my bits to NuGet and share them to any project) and use the command from there. Other projects can add the “command-text” key to their config.json files and specify their own value, or they can feed in the parameter as an arg to the command:

In my sample solution on GitHub. I also have a second project which renames the alias and has it’s own config file that is read in by the command.

Next Steps

All of this opens the doors for some pretty powerful scenarios. Think about what you can do in your build pipeline without having to write, expose and consume custom msbuild targets. You can create commands that are used to build up local databases for new environments or automate the seeding of tables for integration tests. You could add scaffolders and image optimizers and deployment tools and send text messages to your Grandma.

What you should do next is to look at the kinds of things you do when you’re working on your solution – not in it – and think about how you might be able to simplify those tasks. If there are complex parts of your build scripts that you encounter from one project to the next, perhaps you can abstract some of those bits away into a command and then shift to using simplified build scripts that invoke your commands via DNX.

To get some inspiration, check out my sample project on GitHub. the DNX commands for other libraries (such as EF or xUnit ) and try writing a few of your own.

Upgrading NPM in Visual Studio 2015

Converting .NET 4.6 Projects to the VS 2015 Project System

Git is a software tool that is used widely in the linux community for source code management of software projects. There are many open-source projects utilizing Git for source code management, including the linux kernel as well as the Git project itself.

Git is designed to enable a distributed development environment such that multiple developers working on a project need not have a centralized server where the source code is developed and maintained. In other words, Git allows developers working on a project to create local copies of the project and permit development where network access may not exist.

Git provides full revision tracking capabilities and is designed to be efficient, fast and reliable solution for source code management.

Contents

Installing Git

Depending on what Linux distribution you are using on your Linux host there are different options for installing Git. For example, distributions such as Fedora, Ubuntu and Debian have their own software management tool for downloading and installing additional software packages. The Fedora software package manager is called “yum” and the Ubuntu/Debian software package manager is called “apt” (advanced package tool). Hence, for distributions such as Fedora, Ubuntu or Debian, you could use the software package manager to download and install Git. Alternatively, for any Linux distribution you can always download the source, build and install. The following subsections describe how to install Git on Fedora, Ubuntu and Debian distributions and how to install Git from source.

Installing Git on a Ubuntu/Debian Host

To install Git on a Ubuntu/Debian host using the “apt” package manager, as root user simply execute the following command.

Installing Git on a Fedora Host

To install Git on a Fedora host using the “yum” package manager, as root user simply execute the following command.

Installing Git using source on a Linux Host

To install Git using source on a Linux host:

  1. Download the latest Git package from here. For example, the latest available at time of writing was v1.6.0, so file git-1.6.0.tar.bz2 was downloaded.
  2. Extract the archive.
  3. Change directory so that you are in the directory where you extracted Git into.
  4. Execute the “configure” script to make sure that the Linux host has all the required software packages to run Git. Note if packages are missing then please consult the distributions website on how to obtain these packages.
  5. Build the Git package as user by executing the command.
  6. Install the Git package as root user by executing the command.

Configuring Git

Before you start using Git, there are some a few items that you may wish to configured first. When developers are making changes to a Git repository, it is very useful to track which developers made which modifications. To avoid each developer having to manually enter their details for each change they make, users can simply specify the following environment variables and Git will automatically embed these details when changes are made.

When changes are made to a repository, Git allows the user to enter a short description summarizing what modifications have been made. This is another feature that is very beneficial for monitoring changes. To allow a user to enter such a description, Git will start the default text editor on the host. You can override the default text editor used by Git, by setting the following environment variable.

If you are using a BASH shell, then the above environment variables can be defined as follows.

Cloning Git Trees

A very useful feature of Git is the ability to clone repositories that are located on remote hosts. Git supports two protocols for cloning remote repositories and these are HTTP and the Git protocol. The Git protocol is more efficient than HTTP. However, if you host is situated behind a firewall, then chances are the port used by Git will be blocked and so HTTP may be the only protocol you can use.

To clone a remote repository, such as the DaVinci Linux Git tree, you first need to find out the URL where the Git tree is located. For example, the DaVinci Linux Git tree is hosted here. Viewing this website, you will then find a description of the Git tree and you will be able to browse the history of the Git tree. This website for the DaVinci Linux Git tree provides the following information for cloning the Git tree.

To clone one of these trees:

Hence, to clone the repository using the Git protocol you would execute something like the following.

Please note that if you are behind a firewall the Git protocol may not work. It is common for firewalls to block the port used by the Git protocol. If working behind a firewall see Using Git Behind a Firewall

Now although the website for the DaVinci Linux Git tree does not state explicitly that it supports the HTTP protocol for cloning Git tree, you may try using HTTP. However, unless you are behind a firewall where the Git protocol may not work, then it is advised that you use the Git protocol versus HTTP. Additionally, there are no guarantees that HTTP will work. To clone the Git tree using the HTTP protocol you would execute something like the following.

Updating Your Git Tree Clone

The Git trees are frequently updated with new features and patches to fix issues. Once you have made an initial clone of the Git tree, periodically you may wish to sync your local clone with the Git tree you created your clone from. To do this, go to the directory where your Git tree resides and execute the ” git pull ” command.

Viewing the Git History

To view the Git history, simply execute the following command.

The ” git log ” command displays a summary of the updates or commits made to the Git repository in the order of newest to oldest. The below shows a snippet of the output from ” git log ” for the DaVinci Git tree.

Every commit made to the Git tree has a unique 40 digit hexadecimal number that is used to identify the commit. The 40 digit hexadecimal number is usually referred to as the “object name.” From the output of “ git log ” above, the 40 digit object names for the commits can be seen. These object names are calculated using a secure hash algorithm, namely the SHA1 hash. There are many advantages to using the SHA1 hash, because not only does it generate a unique number to track changes, but it also provides a mechanism to detect corruption in the repository.

The ” git log ” command only provides a summary of the changes that were made. To view the details of a specific commit the following command can be used.

For example, to view the details of that commit titled “ARM: DaVinci: Update IO address pointer typechecking” from the above output of the ” git log “, the following command would be executed.

Tags

In the previous section, it was shown that Git uses 40 digit object names, calculated using the SHA1 hash to identify the various commits made to the Git tree. These 40 digit numbers are not something that are easy to remember. Hence, whenever making commits it can be useful to create a “tag” that will be associated with this particular commit. It is up to the user which commits you tag, however, by doing so, it can make it much easier perform merges, comparisons, etc.

When a Git tree is cloned, tags are also inherited from the parent. To view all tags present in the Git tree execute the following command.

Tags are created using the following command.

Tags can be deleted using the following command.

Often times you may want to compare two versions of a file based on tags. For example, suppose you created two tags for “hello.c”, one called “alpha” and another called “beta”. To diff between the two tags use the following command.

The — separates the tag names from the file to be diff’d.

Creating a Development Branch

Git repositories have the concept of “heads” and “branches”. A branch reflects one path of development from a particular state of the repository. A given repository can have unlimited numbers of branches and branches can be created from other branches. Every branch in a repository has an associated branch head. The head is a pointer to the latest commit for the branch.

To view all current branches in a repository simply execute the following command.

After cloinng the DaVinci Git tree, executing “git branch” would show something like the following. Please note that the “ * ” symbol indicates the current branch.

The above shows that the Git repository has three branches. The master branch represents the main branch of the repository. Every Git repository has a master branch. Whenever you create or clone at Git repository a master branch is created automatically. When you clone a repository a branch called “origin” is also created and this represents the Git repository that was cloned. The other branch called “for-rmk” is a custom branch that is present in the Git repository that was cloned. Whenever a repository is cloned, as the name of the command implies, all custom branches are also inherited.

Developers can create custom branches using the “git branch” command for doing experimental work. For example, a new branch called “testing”, to be used for development purposes, can be created by executing the following command. This command will create a new branch with the same state as the current branch.

You may also create a branch based upon any previous state of the Git tree too. For example, executing ” git tag -l ” to list all the tags for the DaVinci Git tree would show something like the following.

You may use any of the above tags to create a new branch from that point in time. For example, to create a new branch called “testing” based on release “v2.6.13” the following command would be executed.

Creating a new branch as shown above does not automatically switch the repository in to the context of the new branch. Switching between branches is performed by using the “ git checkout ” command. For example, the following command would be used to switch to the testing branch.

Similarly to switch from “testing” back to the master branch the following command would be executed.

Branches can always be removed. Therefore, if you created a branch called “testing” and sometime later wished to delete it, you could do so using the below command.

Adding, Editing, Renaming and Removing Files

Once a Git repository has been created or cloned, it may be necessary to add, edit, rename or delete source files in the repository. The following commands allow you to do this.

Please note that after executing any of the above commands, you also need to execute the “ git commit ” command to commit this modification to the repository. For example, suppose you wish to add a new file called “myfile.c” to the repository. To do so the following commands would be executed.

Executing ” git commit “, commits the changes to the Git repository and starts a text editor where you may to enter an commit message to summarise the changes made. The commit messages entered can be viewed by running the ” git log ” command.

Using Git Behind a Firewall

If you are trying to clone git trees from behind a firewall, you may find that it doesn’t work and this is typically due to the fact that the firewall is blocking the port that is used by the Git protocol. You may use HTTP as opposed to Git but there are no guarantees that HTTP will work. You can workaround firewalls and still use the Git protocol by using a tool called corkscrew.

To install corkscrew on a Ubuntu/Debian host using the “apt” package manager, simply execute the following command.

Alternatively, you may download the corkscrew source from here and install as follows.

Create a new file called “git-proxy.sh” with the following contents and replace “<proxy-name>” and “<proxy-port>” with the actual proxy name and proxy port information.

Make sure the file “git-proxy.sh” is executable. To make the file executable execute the following command.

To configure git to always use the proxy whenever you use the git protocol execute the following command.

To configure git to only use the proxy for specific URLs, execute something similar to the following. The below command configures git to use the proxy for all URLs with a kernel.org suffix.

Setting up a Git Server

To setup a simple Git server on a Linux host to enable other users on the same network to clone your Git repositories, first you need to install the “git-daemon” package. To install the git-daemon package on a Ubuntu/Debian host using the “apt” package manager, as root user simply execute the following command.

After installing the “git-daemon” package, it is necessary to configure the server. You may configure the server by editing the file “/etc/sv/git-daemon/run.” To configure the server to export all the git trees in the directory “/pub/gittrees” on the host the file “/etc/sv/git-daemon/run” would be edited as follows.

The path at the end of the “exec” command above indicates where the git trees are located that you wish the servre to export. The option “–export-all” simply tells the server to export all the git trees found in this location. You may configure the server to only export specific git trees. To do so, please see the “git-daemon” manual page for more details. The option “–base-path” remaps all the path requests as relative to the given path. For example, if you run git-daemon with –base-path=/pub/gittrees on example.com, then if you later try to pull git://example.com/hello.git. git-daemon will interpret the path as /pub/gittrees/hello.git.

Git rebase tricks

by Kevin Hilman — ver 0.2

Overview/Intro

Here’s a short overview of a couple of git rebase tricks that I use all the time.

Recommended background reading: Git User’s manual

This has been written with some quilt analogies so folks who are already familiar with using quilt for this will see the equivalents easily. If you’re not familiar with quilt, just ignore the ‘Quilt analogy’ parts.

Quilt analogy: Quilt users are probably used to doing things like:

In git, this is called a rebase.

Interactive rebase: git rebase –interactive (git rebase -i)

Quilt analogy: An interactive rebase is like editing the series file between a ‘quilt pop -a’ and ‘quilt push -a’.

Assume you have a dev branch ‘dev-branch’ based at v2.6.30:

and you want to rebase it on a different upstream head, such as v2.6.31-rc2. However, you’d like to reorganize your commits while doing the rebase. Using interactive rebase, you can drop commits, reorder commits, squash commits (combine multiple commits into a single commit) or edit them interactively before they are rebased.

NOTE: I use A, B, C. above as shorthand for git commit IDs, or git tags.

Assume you want to rebase your dev-branch onto v2.6.31-rc2. To start the interactive rebase, do:

This will bring up an edit window with a list of all the commits to be rebased, and will look something like this:

It is in editing this file that all the magic happens.

Example 1: dropping or re-ordering patches

Quilt analogy: removing or re-ordering patches in the series files

In the edit window, just like a quilt series file, just remove the lines of the commits, or re-order them as you wish.

When done, save the file and rebase will continue.

Resulting tree, assuming C and D dropped, and G moved to the beginning:

Example 2: squashing (combining commits together)

Quilt analogy: quilt fold

Let’s assume that commits D and E are only very minor changes or fixes to commit C and for the rebase, they can just be combined (squashed) into commit C. This kind of thing is often useful for upstream submissions where the upsteram maintainer may not be interested in all the minor edits and fixes along the way, but only in the final result.

To squash D and E into C, change the ‘pick’ for D and E into ‘squash’ (or ‘s’), save the file and rebase will continue.

Git will also combine all the changelogs for all squashed commits into a single changelog and give you a chance to edit/combine the changelog entries as well.

(where C’ is the squashed version of C, D and E)

Example 3: editing commits

Assume that while rebasing, you might want to change a commit slightly. This might be simply to modify the changelog, or to change the patch.

In the edit window, change the ‘pick’ to ‘edit’ (or ‘e’), save the file and rebase will continue until it applies that commit.

When it reaches the ‘edit’ commit it will stop, and give you the chance to make any changes. Make any changes, add them to the index using ‘git add <files-that-were-changed>’ and commit them using ‘git commit –amend’ (NOTE: see rewriting history section of Git User’s manual for more details on –amend.)

When changes are committed, continue rebase with ‘git rebase –continue’.

Also note that additional commits could also be inserted here before continuing either by cherry-picking from other places or by the normal edit/commit cycle.

Partial-tree rebase: git rebase –onto

Example 1

Assume you have a dev branch ‘dev-branch’ based at v2.6.30:

and you want to rebase it on a different upstream head, such as v2.6.31-rc2. However, many of the changes in your dev-branch are already upstream, but may have gone upstream in a different form or were changed by upstream maintainers for various reasons.

In this case, you only want to rebase the parts of your dev-branch that are not upstream.

In this example, assume that commits A..B are already upstream, and you know the ones in your branch will conflict with the upstream versions, so you really only want to rebase commits C..dev-branch.

First, optionally create a branch that keeps track of the old branch in case you need to undo/redo

then, using –onto, to rebase commits C..dev-branch onto v2.6.31-rc2, do:

Alternatively, this can be done in a single step:

Either way, you will end up on the new ‘dev-branch’ and the result will be:

Note in this case, C’ and D’ are the same as C and D except they now have different commit IDs.

References

For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Git here.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply