@@ -78,7 +78,7 @@ static int create_file(const char *path, unsigned int mode)
7878 return open (path , O_WRONLY | O_CREAT | O_EXCL , mode );
7979}
8080
81- static void * read_blob_entry (struct cache_entry * ce , const char * path , unsigned long * size )
81+ static void * read_blob_entry (struct cache_entry * ce , unsigned long * size )
8282{
8383 enum object_type type ;
8484 void * new = read_sha1_file (ce -> sha1 , & type , size );
@@ -93,36 +93,51 @@ static void *read_blob_entry(struct cache_entry *ce, const char *path, unsigned
9393
9494static int write_entry (struct cache_entry * ce , char * path , const struct checkout * state , int to_tempfile )
9595{
96- int fd ;
97- long wrote ;
98-
99- switch ( ce -> ce_mode & S_IFMT ) {
100- char * new ;
101- struct strbuf buf ;
102- unsigned long size ;
103-
96+ unsigned int ce_mode_s_ifmt = ce -> ce_mode & S_IFMT ;
97+ int fd , ret ;
98+ char * new ;
99+ struct strbuf buf = STRBUF_INIT ;
100+ unsigned long size ;
101+ size_t wrote , newsize = 0 ;
102+
103+ switch ( ce_mode_s_ifmt ) {
104104 case S_IFREG :
105- new = read_blob_entry (ce , path , & size );
105+ case S_IFLNK :
106+ new = read_blob_entry (ce , & size );
106107 if (!new )
107108 return error ("git checkout-index: unable to read sha1 file of %s (%s)" ,
108109 path , sha1_to_hex (ce -> sha1 ));
109110
111+ if (ce_mode_s_ifmt == S_IFLNK && has_symlinks && !to_tempfile ) {
112+ ret = symlink (new , path );
113+ free (new );
114+ if (ret )
115+ return error ("git checkout-index: unable to create symlink %s (%s)" ,
116+ path , strerror (errno ));
117+ break ;
118+ }
119+
110120 /*
111121 * Convert from git internal format to working tree format
112122 */
113- strbuf_init (& buf , 0 );
114- if (convert_to_working_tree (ce -> name , new , size , & buf )) {
115- size_t newsize = 0 ;
123+ if (ce_mode_s_ifmt == S_IFREG &&
124+ convert_to_working_tree (ce -> name , new , size , & buf )) {
116125 free (new );
117126 new = strbuf_detach (& buf , & newsize );
118127 size = newsize ;
119128 }
120129
121130 if (to_tempfile ) {
122- strcpy (path , ".merge_file_XXXXXX" );
131+ if (ce_mode_s_ifmt == S_IFREG )
132+ strcpy (path , ".merge_file_XXXXXX" );
133+ else
134+ strcpy (path , ".merge_link_XXXXXX" );
123135 fd = mkstemp (path );
124- } else
136+ } else if ( ce_mode_s_ifmt == S_IFREG ) {
125137 fd = create_file (path , ce -> ce_mode );
138+ } else {
139+ fd = create_file (path , 0666 );
140+ }
126141 if (fd < 0 ) {
127142 free (new );
128143 return error ("git checkout-index: unable to create file %s (%s)" ,
@@ -135,36 +150,6 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
135150 if (wrote != size )
136151 return error ("git checkout-index: unable to write file %s" , path );
137152 break ;
138- case S_IFLNK :
139- new = read_blob_entry (ce , path , & size );
140- if (!new )
141- return error ("git checkout-index: unable to read sha1 file of %s (%s)" ,
142- path , sha1_to_hex (ce -> sha1 ));
143- if (to_tempfile || !has_symlinks ) {
144- if (to_tempfile ) {
145- strcpy (path , ".merge_link_XXXXXX" );
146- fd = mkstemp (path );
147- } else
148- fd = create_file (path , 0666 );
149- if (fd < 0 ) {
150- free (new );
151- return error ("git checkout-index: unable to create "
152- "file %s (%s)" , path , strerror (errno ));
153- }
154- wrote = write_in_full (fd , new , size );
155- close (fd );
156- free (new );
157- if (wrote != size )
158- return error ("git checkout-index: unable to write file %s" ,
159- path );
160- } else {
161- wrote = symlink (new , path );
162- free (new );
163- if (wrote )
164- return error ("git checkout-index: unable to create "
165- "symlink %s (%s)" , path , strerror (errno ));
166- }
167- break ;
168153 case S_IFGITLINK :
169154 if (to_tempfile )
170155 return error ("git checkout-index: cannot create temporary subproject %s" , path );
0 commit comments