Edit a Git commit

In the daily use of a version control system, it can happens to commit wrong data or worse, sensitive data; if we are using Git, we can solve this problem with an interactive rebase.

Interactive rebase

As you know, the rebase is a Git command that allows you to reapply a bunch of commits on the top of another branch; what you need to do is fix the bad commit and reapply, with the bunch of the commits above, to the top of the branch.

So, the first step is the git rebase command with the option -i; this option allows you to have an interactive session where you can choose to edit one of the commits following the commit selected:


git rebase [<commit>] -i

Once the command is executed, and interactive console is showed:

git console

At the top, it’s showed the list of the commits above the commit specified in the rebase command; the first word is the command that you want do do with the commit; in this case, we want to change the a59a72d commit, so we change the command from pick to edit.

Than, confirm this change with a combination of commands:


esc: wq

The console command terminated and now you can make changes to the bad file and fix it, for example web.config.

Once do that, you need to add the file to the Git staging area:


git add Web.config

Commit amend option

Now you can commit these changes; what we need to do is reapply the bunch of commits to the current branch, and we can do that with the amend option of the commit command:


git commit --amend

This option replace the tip of the branch with the new commit.

The next step is continue the rebase process and confirm the fix to the commit:


git rebase --continue

At this point, the local branch tip and the remote branch tip are not the same because of the “commit –amend”; so, if you proceed with a simple git push origin, the command refuse to update the remote branch because the remote reference is not an ancestor of the local reference.

In order to do that, you need to use the –force option, that you can specify for a specific branch by putting the + character before the branch name.

Before do that, keep in the mind the Golden Rule of Rebasing: you never use rebase on public branches, because this command rewrite the history and you can potentially lost the commits of the other developers.


git push origin +[<branch name>]

After that, the local and remote branch will be updated correctly and the bad commit will be fixed.

 

 

Advertisements
Edit a Git commit

Add Bower in an ASP.NET 4.5 application

Bower is packager manager that allow you to manage the client packages of your application and it can be easily integrated with in a deploy workflow with a task runner like Gulp.

In this example, the sample application is an ASP.NET application with some NuGet packages installed and using Gulp to automate the deploy workflow.

With Bower you can manage packages like AngularJS, Boostrap, JQuery and so on; it’s a front-end package manager and it can be installed with npm (Node.js Package manager) :

npm install bower -g

In order to using Bower in an ASP.NET application, the first step is adding the bower.json file:

bower

Bower install the packages in the path defined in the file .bowerrc and you can change it:

{
"directory": "bower_components"
}

Now you can using Bower to install the client packages which the application needs.

Once of the packages installed with NuGet on the existing application is AngularJS; it can be installed with Bower:

bower install angular –save

With the option –save, the bower.json file will be updated:

{
"name": "angular-signalr",
"private": true,
"main": [
""
],
"dependencies": {
"angular": "~1.5.5",
}
}

You can do the same operation for the other packages of the application; they will be installed in the bower_components path and new rows will be added in the bower.json file:

{
"name": "angular-signalr",
"private": true,
"main": [
""
],
"dependencies": {
"angular": "~1.5.5",
"angular-bootstrap": "angular-ui-bootstrap-bower#~1.3.2",
"angular-ui-router": "~0.2.18",
"AngularJS-Toaster": "aangular-toaster#~0.4.11",
"angular-loading-bar": "~0.9.0",
"angular-animate": "~1.5.5",
"angular-resource": "~1.5.5",
"bootstrap": "~3.3.6",
"jquery-ui": "~1.11.4",
"jquery": "~2.2.3",
"signalr": "~2.2.0",
"q": "1.0.1"
}
}

Now what we need to do is automate the workflow and inject these packages in the index page; you can do that with two Gulp plugins:

npm install –save-dev gulp-bower

npm install –save wiredep

You can find exhaustive documentation about these two plugins on the npm site.

The next step is adding the dependencies in the gulpfile.js of the application and creating the new task:

'use strict';

var gulp = require('gulp'),
bower = require('gulp-bower'),
wiredep = require('wiredep').stream

gulp.task('bower', function () {
return bower();
});

gulp.task('wiredep', ['bower'], function () {
var source = gulp.src('./' + config.indexDev);

return source.pipe(wiredep({}))
.pipe(gulp.dest('.'));
});

The main html file need to be changed, in order to make wiredep working:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Angular SignalR Application</title>

  <!-- build:css Content/lib.min.css -->
  <!-- bower:css  -->
  <!-- endbower -->
  <!-- endbuild -->

  <!-- build:js Scripts/lib.min.js -->
  <!-- bower:js  -->
  <!-- endbower -->
  <!-- endbuild -->
</head>
<body ng-app="angularSignalR">
</body>
</html>

In the bower.json file you need also specify the main application modules:

{
"name": "angular-signalr",
"private": true,
"main": [
""
],
"dependencies": {
"angular": "~1.5.5",
"angular-bootstrap": "angular-ui-bootstrap-bower#~1.3.2",
"angular-ui-router": "~0.2.18",
"AngularJS-Toaster": "aangular-toaster#~0.4.11",
"angular-loading-bar": "~0.9.0",
"angular-animate": "~1.5.5",
"angular-resource": "~1.5.5",
"bootstrap": "~3.3.6",
"jquery-ui": "~1.11.4",
"jquery": "~2.2.3",
"signalr": "~2.2.0",
"q": "1.0.1"
},
"overrides": {
"angular": {
"main": [
"angular.js"
]
},
"angular-bootstrap": {
"main": [
"ui-bootstrap-csp.css",
"ui-bootstrap.js",
"ui-bootstrap-tpls.js"
]
},
"angular-ui-router": {
"main": [
"release/angular-ui-router.js"
]
},
"AngularJS-Toaster": {
"main": [
"toaster.css",
"toaster.js"
]
},
"angular-loading-bar": {
"main": [
"src/loading-bar.css",
"src/loading-bar.js"
]
},
"angular-animate": {
"main": [
"angular-animate.js"
]
},
"angular-resource": {
"main": [
"angular-resource.js"
]
},
"bootstrap": {
"main": [
"dist/css/bootstrap.css",
"dist/js/bootstrap.js"
]
},
"jquery": {
"main": [
"dist/jquery.js"
]
},
"jquery-ui": {
"main": [
"jquery-ui.js"
]
},
"q": {
"main": [
"q.js"
]
},
"signalr": {
"main": [
"jquery.signalR.js"
]
}
}
}

Now the configuration is completed and you can run the gulp tasks; once verified that the application works correctly, you can proceed with uninstalling the NuGet packages managed with bower; for example unistall AngularJS:

uninstall package AngularJS

You can find the project here.

 

 

 

 

Add Bower in an ASP.NET 4.5 application

Angular implicit annotation with Gulp

As you know, AngularJS provide the management of the module dependencies through the dependency injection.

In order to be able to manage these dependencies, Angular allows specific annotations that the developers can use to define their modules.

Dependency Annotation

For example, in an Angular application written with Typescript, the dependencies can be inject in the run method with this syntax:


AngularSignalR.module.config(['$stateProvider', '$urlRouterProvider', ($stateProvider, $urlRouterProvider) =&gt; {
$urlRouterProvider.otherwise(&quot;/orders&quot;);

$stateProvider
.state('Orders', {
url: '/orders',
templateUrl: '/app/views/orders.html',
controller: 'OrdersController as vm'
});
}]);

This is the most used syntax and is called Inline Array Annotation; another option is using the $inject property:


module AngularSignalRApp.Controllers {

export class ModalsController {
private modalInstance: ng.ui.bootstrap.IModalServiceInstance;

public static $inject = ['$uibModalInstance'];

constructor(modalInstance: ng.ui.bootstrap.IModalServiceInstance) {
this.modalInstance = modalInstance;
}

}

AngularSignalR.module.controller('ModalsController', ModalsController);
}

The order specified in the $inject property must match the controller arguments; this is the Property Annotation.

The last options allow to leave out the manual injection of the parameters and assuming that the parameter names are the names of the dependencies; this is called implicit annotation:


module AngularSignalRApp.Controllers {

export class ModalsController {
private modalInstance: ng.ui.bootstrap.IModalServiceInstance;

constructor($uibModalInstance: ng.ui.bootstrap.IModalServiceInstance) {
this.modalInstance = $uibModalInstance;
}
}

AngularSignalR.module.controller('ModalsController', ModalsController);
}

Gulp plugin

Unfortunately, the implicit annotation doesn’t work with the minification process due to the rename of the parameters.

You can work around this problem by using the Gulp plugin gulp-ng-annotate; first of all, you need to install it as a project dev dependency:

npm install gulp-ng-annotate –save-dev

And add it in the gulpfile.js of the web application:


var gulp = require('gulp'),
ngAnnotate = require('gulp-ng-annotate')

Now you need to add the plugin inside the task that execute the minification process.

In this application it’s used gulp-useref, and you need to add the plugin before the uglify process:


gulp.task('useref', ['inject'], function () {
var source = gulp.src(config.indexDev);
var jsFilter = filter('**/*.js', { restore: true });
var cssFilter = filter('**/*.css', { restore: true });

return source
.pipe(useref())
.pipe(cssFilter)
.pipe(cleanCss())
.pipe(cssFilter.restore)
.pipe(jsFilter)
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(jsFilter.restore)
.pipe(rev())
.pipe(revReplace())
.pipe(gulp.dest(config.dist));
});

With this operations, we can using implicit annotation without encountering problems after minification process.

You can find the project here.

 

 

Angular implicit annotation with Gulp

Compile Typescript with Gulp

Gulp is a build tools that can be used, among other things, as a Typescript compiler and sourcemaps generator.
As you know, Typescript is a superset of Javascript which offer you static typing, classes, interfaces;  Sourcemaps are additional files that allow you to debug, from the browser debugger, source files (typescript files) instead of Javascript files.

Visual Studio Typescript build

Every time you save a Typescript file from Visual Studio, you can see that the associated js and maps files are updated; this option can be manage in the project settings:

compileOnSave
And the same event occur every time the project is built; to disable this feature, there is an option in the typescript property file:

typescriptProperty

Once you changed this setting for all typescript files, the Visual Studio Typescript compiling is disabled and the typescript files will no longer been updated.

Tasks

In order to compile Typescript files with Gulp, you need to install these plugins:

npm install gulp-typescript –save

npm install gulp-sourcemaps –save

The first plugin is to compile Typescript and generate Javascript files; the second one is the plugin for Sourcemaps.

Once installed you need to include them in the gulpfile.js:

var gulp = require('gulp'),
ts = require('gulp-typescript'),
sourcemaps = require('gulp-sourcemaps')

The next step is to write the Gulp task:


var tsProject = ts.createProject({
target: 'ES5',
module: 'CommonJS',
noExternalResolve: false,
noEmitOnErrors: true,
noImplicitAny: true
});

gulp.task('typescript', function () {
var tsResult = gulp.src(config.ts)
.pipe(sourcemaps.init())
.pipe(ts(tsProject));

return tsResult.js
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(config.jsBasePath));
});

There are several options for the Typescript compiler; one of that is the external module system, which in case of Node.js is CommonJS.

Another option is noImplicitAny that force the developer to declare the type for any object used in the Typescript file.

Now you can run the task and see the files in the app folder:

files

The last step is enable build every time a typescript file is saved; in order to do that, you can use gulp watch:

gulp.task('watchTypescript', ['typescript'], function () {
gulp.watch(config.ts, ['typescript']);
});

You can find the project here.

Compile Typescript with Gulp