The problem is, you start the http get request and waiting for the response. Meanwhile you are scrolling up and done and your function would be called again. That could be the reason why the last posts are loaded multiple times. However, and if the query was successful than you are adding newList.length to your offset. Possible solution for this problem:
$scope.offset = 0;
$scope.posts = [];
$scope.isBusy = false;
$scope.loadMore = function(){
if($scope.isBusy === true) return; // request in progress, return
$scope.isBusy = true;
$http.get('/getposts?offset='+$scope.offset)
.success(function(data){
var newList = data.post_list;
if(newList.length>0){
for(var x=0; x<newList.length; x++){
$scope.posts.push(newList[x]);
}
$scope.offset+=newList.length;
}
$scope.isBusy = false; // request processed
});
}